-
Notifications
You must be signed in to change notification settings - Fork 0
/
Bone.pde
179 lines (149 loc) · 5.74 KB
/
Bone.pde
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
import shiffman.box2d.*;
// =============================================
// CLASS BONE (from the Muscular Model Framework)
// by Guillem Benavent (Updated: 23/7/2023)
// For Research Project at Taradell School
// =============================================
// A bone uses a Box2D body to model a phisical bone.
// It is defined by its location (x,y) and it's measurements (length and width).
// It's displayed as a white rectangl with the measurements set during the creation.
// =============================================
class Bone
{
color BONE_COLOR = color(255, 255, 240);
float BONE_FRICTION = 8;
float BONE_ELASTICITY = 0.5;
float BONE_DENSITY = 1900; // 1900 kg/m3;
// Bone Properties
public Body body;
float posX;
float posY;
float sizeLength;
float sizeWidth;
float sizeDepth;
String name;
Bone(float posX_, float posY_, float length_, float width_)
{
this(new String("Unknown Bone #")+random(100,999), posX_, posY_, length_, width_, width_, false);
}
Bone(float posX_, float posY_, float length_, float width_, float depth_)
{
this(new String("Unknown Bone #")+random(100,999), posX_, posY_, length_, width_, depth_, false);
}
Bone(String name, float posX_, float posY_, float length_, float width_)
{
this(name, posX_, posY_, length_, width_, width_, false);
}
Bone(String name, float posX_, float posY_, float length_, float width_, float depth_)
{
this(name, posX_, posY_, length_, width_, depth_, false);
}
Bone(String name, float posX_, float posY_, float length_, float width_, float depth_, boolean isStatic)
{
this.name = name;
posX = posX_;
posY = posY_;
sizeLength = length_;
sizeWidth = width_;
sizeDepth = depth_;
// Create BodyDef
BodyDef bodyDef = new BodyDef();
bodyDef.type = isStatic ? BodyType.STATIC : BodyType.DYNAMIC;
bodyDef.position.set(posX, posY);
bodyDef.linearDamping = BONE_FRICTION;
bodyDef.angularDamping = BONE_FRICTION;
bodyDef.bullet = true;
body = box2d.createBody(bodyDef);
// Create Shape
PolygonShape shape = new PolygonShape();
shape.setAsBox( sizeLength/2, sizeWidth/2);
//^ setAsBox(w,h) > [-w,h][+w,h][+w,-h][-w,-h]
// Create fixture with shape
FixtureDef fixDef = new FixtureDef();
fixDef.shape = shape;
fixDef.density = BONE_DENSITY*sizeDepth*2; // Divided by depth to get the 2d density kg/m2
fixDef.friction = BONE_FRICTION;
fixDef.restitution = BONE_ELASTICITY;
fixDef.isSensor = true;
// Attach Shape to Body through Fixture
body.createFixture(fixDef);
println("Bone "+name+" Created: Weight = "+body.m_mass+" kg");
}
void display(float displayScale)
{
//Vec2 pix = box2d.getBodyPixelCoord(body);
Vec2 posCenter = body.getWorldCenter();
Vec2 pix = new Vec2(box2d.coordWorldToPixels(posCenter.x*displayScale, posCenter.y*displayScale));
float a = body.getAngle();
float pixLength = box2d.scalarWorldToPixels(sizeLength)*displayScale;
float pixWidth = box2d.scalarWorldToPixels(sizeWidth)*displayScale;
float pixCornerRadius = min(pixWidth, pixLength)/3;
pushMatrix();
translate(pix.x, pix.y);
rotate(-a);
fill(BONE_COLOR);
stroke(0);
rectMode(CENTER);
rect(0, 0, pixLength, pixWidth, pixCornerRadius);
//fill(color(255, 0, 0));
//stroke(BONE_COLOR);
//ellipse((pixWidth-pixLength)/2, 0, pixWidth, pixWidth);
//ellipse((pixLength-pixWidth)/2, 0, pixWidth, pixWidth);
//PShape bone = createShape(GROUP);
//rectMode(CENTER);
//PShape body = createShape(RECT, 0, 0, pixLength-pixWidth, pixWidth);
//PShape headLeft = createShape(ELLIPSE, (pixWidth-pixLength)/2, 0, pixWidth, pixWidth);
//PShape headRight = createShape(ELLIPSE, (pixLength-pixWidth)/2, 0, pixWidth, pixWidth);
//bone.addChild(body);
//bone.addChild(headLeft);
//bone.addChild(headRight);
//bone.fill(color(255, 0, 0));
//bone.noStroke();
//shape(bone);
popMatrix();
}
void printDetails(String name)
{
println("Bone Details of '"+name+"'");
int fixtureCounter=0;
for (Fixture f = body.getFixtureList(); f!=null ; f = f.getNext())
{
fixtureCounter++;
println("- Fixture #"+fixtureCounter+":");
ShapeType shapeType = f.getType();
if ( shapeType == ShapeType.POLYGON )
{
PolygonShape polygonShape = (PolygonShape)f.getShape();
int vertexCount = polygonShape.getVertexCount();
println(" - Type: POLYGON ("+vertexCount+" vertices)");
// Relative Corners
float relSumX = 0;
float relSumY = 0;
print(" - Relative Vertices: ");
for (int v=0; v<vertexCount; v++)
{
Vec2 vertex = polygonShape.getVertex(v);
print("("+(vertex.x)+","+(vertex.y)+") ");
relSumX = relSumX+vertex.x;
relSumY = relSumY+vertex.y;
}
println();
println(" - Relative Average Center: ("+(relSumX/vertexCount)+", "+(relSumY/vertexCount)+")");
// Absolute Corners
float absSumX = 0;
float absSumY = 0;
print(" - Absolute Vertices: ");
for (int v=0; v<vertexCount; v++)
{
Vec2 vertex = polygonShape.getVertex(v);
print("("+(posX+vertex.x)+","+(posY+vertex.y)+") ");
absSumX = absSumX+posX+vertex.x;
absSumY = absSumY+posY+vertex.y;
}
println();
println(" - Absolute Average Center: ("+(absSumX/vertexCount)+", "+(absSumY/vertexCount)+")");
}
}
println();
}
}