summaryrefslogtreecommitdiff
path: root/3d/rigidbody/main.cpp
diff options
context:
space:
mode:
Diffstat (limited to '3d/rigidbody/main.cpp')
-rw-r--r--3d/rigidbody/main.cpp219
1 files changed, 134 insertions, 85 deletions
diff --git a/3d/rigidbody/main.cpp b/3d/rigidbody/main.cpp
index 90c6bc8..bf6af58 100644
--- a/3d/rigidbody/main.cpp
+++ b/3d/rigidbody/main.cpp
@@ -52,7 +52,7 @@ struct Rigidbody3d {
void update(float32 deltaTimeSeconds) {
// Apply gravity
- //velocity += (Vector3 { 0.f, -9.8f, 0.f } * deltaTimeSeconds);
+ velocity += (Vector3 { 0.f, -9.8f, 0.f } * deltaTimeSeconds);
Vector3 force = { 0.f, 0.f, 0.f };
Vector3 torque = { 0.f, 0.f, 0.f };
@@ -69,8 +69,6 @@ struct Rigidbody3d {
Vector3 forceToApply = i.force * (impulseDtSeconds / i.timeOfApplicationSeconds);
force += forceToApply;
- force.printDebug("Force applied\n");
-
torque += i.pointOfApplication.cross(force).dot(forceToApply);
i.timeAppliedSeconds = nextTimeAppliedSeconds;
}
@@ -82,9 +80,12 @@ struct Rigidbody3d {
Vector3 rotationalAcceleration = torque / momentOfInertia;
rotationalVelocity += (rotationalAcceleration * deltaTimeSeconds);
- Quaternion rotationVelocityQuat = { 0, rotationalVelocity.x, rotationalVelocity.y, rotationalVelocity.z };
- Quaternion dqDt = (rotationVelocityQuat * rotation) * 0.5f;
- rotation = rotation + (dqDt * deltaTimeSeconds);
+ Vector3 drDt = rotationalVelocity * deltaTimeSeconds;
+
+ Quaternion rotationVelocityQuat = quaternionFromRotation(Vector3(1, 0, 0), drDt.x)
+ * quaternionFromRotation(Vector3(0, 1, 0), drDt.y)
+ * quaternionFromRotation(Vector3(0, 0, 1), drDt.z);
+ rotation = rotation * rotationVelocityQuat;
for (int32 idx = 0; idx < numImpulses; idx++) {
if (activeImpulses[idx].isDead) {
@@ -99,85 +100,113 @@ struct Rigidbody3d {
}
};
-struct Cube {
+float32 bounds = 20.f;
+
+struct Sphere {
Mesh3d mesh;
Rigidbody3d body;
- float32 scale = 10.f;
void load(Renderer3d* renderer) {
- Vertex3d cubeVertices[] = {
- {
- Vector3 { 1.f, 1.f, 1.f },
- Vector3(),
- colorFromHex(255.f, 0.f, 0.f, 255.f)
- },
- {
- Vector3 { -1.f, 1.f, 1.f },
- Vector3(),
- colorFromHex(0.f, 255.f, 0.f, 255.f)
- },
- {
- Vector3 { -1.f, 1.f, -1.f },
- Vector3(),
- colorFromHex(0.f, 0.f, 255.f, 255.f)
- },
- {
- Vector3 { 1.f, 1.f, -1.f },
- Vector3(),
- colorFromHex(255.f, 0.f, 255.f, 255.f)
- },
- {
- Vector3 { 1.f, -1.f, 1.f },
- Vector3(),
- colorFromHex(255.f, 255.f, 0.f, 255.f)
- },
- {
- Vector3 { -1.f, -1.f, 1.f },
- Vector3(),
- colorFromHex(255.f, 0.f, 0.f, 255.f)
- },
- {
- Vector3 { -1.f, -1.f, -1.f },
- Vector3(),
- colorFromHex(0.f, 0.f, 255.f, 255.f)
- },
- {
- Vector3 { 1.f, -1.f, -1.f },
- Vector3(),
- colorFromHex(255.f, 255.f, 0.f, 255.f)
- }
- };
-
-
- uint32 cubeIndices[] = {
- 0, 1, 3, //top 1
- 3, 1, 2, //top 2
- 2, 6, 7, //front 1
- 7, 3, 2, //front 2
- 7, 6, 5, //bottom 1
- 5, 4, 7, //bottom 2
- 5, 1, 4, //back 1
- 4, 1, 0, //back 2
- 4, 3, 7, //right 1
- 3, 4, 0, //right 2
- 5, 6, 2, //left 1
- 5, 1, 2 //left 2
- };
-
-
- mesh.load(&cubeVertices[0], 8, cubeIndices, 36, renderer);
+ const float32 scale = 3.f;
+ const float32 angleIncrements = 2.f;
+ const int32 numFaces = static_cast<int32>((180.f / angleIncrements + 1) * (360.f / angleIncrements + 1));
+ const int32 numVertices = 4.f * numFaces;
+ const int32 numIndices = 6 * numFaces;
+ Vertex3d* vertices = new Vertex3d[numVertices];
+ GLuint* indices = new GLuint[numIndices];
+
+ // Generate vertices and indices
+ GLint index = 0;
+ int32 vidx = 0;
+ int32 iidx = 0;
+ for (float phi = 0.0; phi <= 180; phi += angleIncrements) {
+ const auto cosPhi = cos(DEG_TO_RAD(phi));
+ const auto sinPhi = sin(DEG_TO_RAD(phi));
+
+ const auto nextCosPhi = cos(DEG_TO_RAD(phi + angleIncrements));
+ const auto nextSinPhi = sin(DEG_TO_RAD(phi + angleIncrements));
+
+ for (float theta = 0.0; theta <= 360; theta += angleIncrements) {
+ auto color = colorFromHex(randomFloatBetween(0.f, 255.f), randomFloatBetween(0.f, 255.f), randomFloatBetween(0.f, 255.f), 255.f);
+ const auto cosTheta = cos(DEG_TO_RAD(theta));
+ const auto sinTheta = sin(DEG_TO_RAD(theta));
+
+ const auto nextSinTheta = sin(DEG_TO_RAD(theta + angleIncrements));
+ const auto nextCosTheta = cos(DEG_TO_RAD(theta + angleIncrements));
+
+ // Top Left Point
+ auto topLeftPoint = Vector3(scale * sinPhi * cosTheta, scale * sinPhi * sinTheta, scale * cosPhi);
+ auto topLeftIdx = index++;
+ vertices[vidx++] = { topLeftPoint, topLeftPoint.normalize(), color };
+
+ // Bottom Left Point
+ auto bottomLeftPoint = Vector3(scale * nextSinPhi * cosTheta, scale * nextSinPhi * sinTheta, scale * nextCosPhi);
+ auto bottomLeftIdx = index++;
+ vertices[vidx++] = { bottomLeftPoint, bottomLeftPoint.normalize(), color };
+
+ // Bottom Right Point
+ auto bottomRightPoint = Vector3(scale * nextSinPhi * nextCosTheta, scale * nextSinPhi * nextSinTheta, scale * nextCosPhi);
+ auto bottomRightIdx = index++;
+ vertices[vidx++] = { bottomRightPoint, bottomRightPoint.normalize(), color };
+
+ // Top Right Point
+ auto topRightPoint = Vector3(scale * sinPhi * nextCosTheta, scale * sinPhi * nextSinTheta, scale * cosPhi);
+ auto topRightIdx = index++;
+ vertices[vidx++] = { topRightPoint, topRightPoint.normalize(), color };
+
+ indices[iidx++] = (topLeftIdx);
+ indices[iidx++] = (bottomLeftIdx);
+ indices[iidx++] = (bottomRightIdx);
+ indices[iidx++] = (bottomRightIdx);
+ indices[iidx++] = (topLeftIdx);
+ indices[iidx++] = (topRightIdx);
+ }
+ }
+
+ mesh.load(vertices, numVertices, indices, numIndices, renderer);
body.position = Vector3 { 0.f, 0.f, 0.f };
body.velocity = Vector3 { 0.f, 0.f, 0.f };
- mesh.model = Mat4x4().scale(scale);
- float32 singleFaceArea = scale * scale;
+ float32 singleFaceArea = scale;
body.momentOfInertia = (body.mass * singleFaceArea) / 6.f;
+
+ delete [] vertices;
+ delete [] indices;
}
void update(float32 dtSeconds) {
body.update(dtSeconds);
- mesh.model = mesh.model.translate(body.position) * body.rotation.toMatrix();
+
+ if (body.position.x > bounds) {
+ body.position.x = bounds;
+ body.velocity.x = -body.velocity.x;
+ }
+ else if (body.position.x < -bounds) {
+ body.position.x = -bounds;
+ body.velocity.x = -body.velocity.x;
+ }
+
+ if (body.position.y > bounds) {
+ body.position.y = bounds;
+ body.velocity.y = -body.velocity.y;
+ }
+ else if (body.position.y < -bounds) {
+ body.position.y = -bounds;
+ body.velocity.y = -body.velocity.y;
+ }
+
+ if (body.position.z > bounds) {
+ body.position.z = bounds;
+ body.velocity.z = -body.velocity.z;
+ }
+ else if (body.position.z < -bounds) {
+ body.position.z = -bounds;
+ body.velocity.z = -body.velocity.z;
+ }
+
+ mesh.model = body.rotation.toMatrix().translate(body.position);
+
}
void render(Renderer3d* renderer) {
@@ -202,7 +231,9 @@ Renderer3d renderer;
Camera3d camera;
MainLoop mainLoop;
bool isIntersectingPointer = false;
-Cube cube;
+
+const int32 numSpheres = 2;
+Sphere sphereList[numSpheres];
int main() {
context.init("#gl_canvas");
@@ -214,26 +245,42 @@ int main() {
void load() {
renderer.load(&context);
- cube.scale = 12.f;
- cube.body.mass = 100.f;
- cube.load(&renderer);
- camera.projection = Mat4x4().getPerspectiveProjection(0.1f, 10000.f, DEG_TO_RAD(60.f), 800.f / 600.f);
- camera.view = Mat4x4().translate({ 0, 0, -250 });
+
+ sphereList[0].load(&renderer);
+ sphereList[0].body.mass = 10.f;
+ sphereList[0].body.position = Vector3(10.f, 0, -5);
+ sphereList[0].body.velocity = Vector3(-10.f, 10.f, 10.f);
+ sphereList[0].body.rotationalVelocity = Vector3(1.f, 1.f, 1.f);
+
+ sphereList[1].load(&renderer);
+ sphereList[1].body.mass = 6.f;
+ sphereList[1].body.position = Vector3(-10.f, 0, 5);
+ sphereList[1].body.velocity = Vector3(10.f, 10.f, -10.f);
+ sphereList[1].body.rotationalVelocity = Vector3(1.f, 1.f, 1.f);
+
+ camera.projection = Mat4x4().getPerspectiveProjection(0.1f, 10000.f, DEG_TO_RAD(45.f), 800.f / 600.f);
+ camera.view = Mat4x4().translate({ 0, 0, -40.f });
mainLoop.run(update);
}
void update(float32 deltaTimeSeconds, void* userData) {
- cube.update(deltaTimeSeconds);
-
+ for (int32 idx = 0; idx < numSpheres; idx++) {
+ sphereList[idx].update(deltaTimeSeconds);
+ }
+
// Renderer
renderer.render(&camera);
- cube.render(&renderer);
+ for (int32 idx = 0; idx < numSpheres; idx++) {
+ sphereList[idx].render(&renderer);
+ }
}
void unload() {
mainLoop.stop();
renderer.unload();
- cube.unload();
+ for (int32 idx = 0; idx < numSpheres; idx++) {
+ sphereList[idx].unload();
+ }
}
//
@@ -255,8 +302,10 @@ EM_BOOL onStopClicked(int eventType, const EmscriptenMouseEvent* mouseEvent, voi
EM_BOOL onForceApplicationRequested(int eventType, const EmscriptenMouseEvent* mouseEvent, void* userData) {
printf("Force applied\n");
Impulse base;
- base.force = { 0, 1000, 0 };
- base.pointOfApplication = { 0, 1, 0 };
- cube.body.applyImpulse(base);
+ base.force = { 0, 10000, 0 };
+ base.pointOfApplication = { -15, -15, 0 };
+ for (int32 idx = 0; idx < numSpheres; idx++) {
+ sphereList[idx].body.applyImpulse(base);
+ }
return true;
}