diff options
Diffstat (limited to '3d/rigidbody/main.cpp')
-rw-r--r-- | 3d/rigidbody/main.cpp | 219 |
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; } |