/* This function simply turns the orientation and position of our physics node into a transformation matrix, suitable for plugging into our Renderer! It is cleaner to work with matrices when it comes to rendering, as it is what shaders expect, and allow us to keep all of our transforms together in a single construct. But when it comes to physics processing and 'game-side' logic, it is much neater to have seperate orientations and positions. */ Matrix4 PhysicsNode::BuildTransform() { Matrix4 m = m_orientation.ToMatrix(); m.SetPositionVector(m_position); return m; }
Matrix4 Matrix4::BuildViewMatrix(const Vector3 &from, const Vector3 &lookingAt, const Vector3 up /*= Vector3(1,0,0)*/ ) { Matrix4 r; r.SetPositionVector(Vector3(-from.x,-from.y,-from.z)); Matrix4 m; Vector3 f = (lookingAt - from); f.Normalise(); Vector3 s = Vector3::Cross(f,up); Vector3 u = Vector3::Cross(s,f); m.values[0] = s.x; m.values[4] = s.y; m.values[8] = s.z; m.values[1] = u.x; m.values[5] = u.y; m.values[9] = u.z; m.values[2] = -f.x; m.values[6] = -f.y; m.values[10] = -f.z; return m*r; }
Matrix4 Particles::BuildTransform() { copyArrayFromDevice(buoyancy, buoyancyGpu, 0, sizeof(float)* 4 * numParticles); copyArrayFromDevice(buoyancyAng, buoyancyAngGpu, 0, sizeof(float)* 4 * numParticles); float* force = new float[4]; for (int i = 0; i < numParticles; i++) { force[0] += buoyancy[i * 4]; force[1] += buoyancy[i * 4 + 1]; force[2] += buoyancy[i * 4 + 2]; force[3] = 0; Vector3 ang = Vector3(buoyancyAng[i * 4], buoyancyAng[i * 4 + 1], buoyancyAng[i * 4 + 2]); if (ang.x != 0 || ang.y != 0 || ang.z != 0) { orientation = orientation + orientation * (ang / 20000000.0f); orientation.Normalise(); } } force[1] -= 9.81f * 2000.0f; for (int i = 0; i < 4; i++) { solidVel[i] = solidVel[i] + force[i] * mparams.timeStep; } CheckEdges(solidPos, solidVel); copyArrayToDevice(solidPosGpu, solidPos, 0, 4 * sizeof(float)); copyArrayToDevice(solidVelGpu, solidVel, 0, 4 * sizeof(float)); //orientation.Normalise(); Matrix4 m = orientation.ToMatrix(); Vector3 p = Vector3(solidPos[0], solidPos[1], solidPos[2]); m.SetPositionVector(p); return m; }
void MD5Node::DebugDrawJointTransforms(float size, bool worldSpace) { //Temporary VAO and VBO unsigned int skeletonArray; unsigned int skeletonBuffer; unsigned int skeletonColourBuffer; glGenVertexArrays(1, &skeletonArray); glGenBuffers(1, &skeletonBuffer); glGenBuffers(1, &skeletonColourBuffer); //Temporary chunk of memory to keep our joint positions in int numVerts = currentSkeleton.numJoints * 6; Vector3* skeletonVertices = new Vector3[numVerts]; Vector4* skeletonColours = new Vector4[numVerts]; for (int i = 0; i < currentSkeleton.numJoints; ++i) { Matrix4 transform = (worldSpace ? currentSkeleton.joints[i].transform : currentSkeleton.joints[i].localTransform); Vector3 start = transform.GetPositionVector(); transform.SetPositionVector(Vector3(0, 0, 0)); Vector4 endX = transform * Vector4(1, 0, 0, 1); Vector4 endY = transform * Vector4(0, 1, 0, 1); Vector4 endZ = transform * Vector4(0, 0, 1, 1); skeletonVertices[(i * 6) + 0] = currentSkeleton.joints[i].transform.GetPositionVector(); skeletonVertices[(i * 6) + 1] = currentSkeleton.joints[i].transform.GetPositionVector() + (endX.ToVector3() * size); skeletonVertices[(i * 6) + 2] = currentSkeleton.joints[i].transform.GetPositionVector(); skeletonVertices[(i * 6) + 3] = currentSkeleton.joints[i].transform.GetPositionVector() + (endY.ToVector3() * size); skeletonVertices[(i * 6) + 4] = currentSkeleton.joints[i].transform.GetPositionVector(); skeletonVertices[(i * 6) + 5] = currentSkeleton.joints[i].transform.GetPositionVector() + (endZ.ToVector3() * size); skeletonColours[(i * 6) + 0] = Vector4(1, 0, 0, 1); skeletonColours[(i * 6) + 1] = Vector4(1, 0, 0, 1); skeletonColours[(i * 6) + 2] = Vector4(0, 1, 0, 1); skeletonColours[(i * 6) + 3] = Vector4(0, 1, 0, 1); skeletonColours[(i * 6) + 4] = Vector4(0, 0, 1, 1); skeletonColours[(i * 6) + 5] = Vector4(0, 0, 1, 1); } //You should know what this all does by now, except we combine it with the draw operations in a single function glBindVertexArray(skeletonArray); glBindBuffer(GL_ARRAY_BUFFER, skeletonBuffer); glBufferData(GL_ARRAY_BUFFER, currentSkeleton.numJoints*sizeof(Vector3) * 6, skeletonVertices, GL_STREAM_DRAW); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0); glEnableVertexAttribArray(0); glBindBuffer(GL_ARRAY_BUFFER, skeletonColourBuffer); glBufferData(GL_ARRAY_BUFFER, currentSkeleton.numJoints*sizeof(Vector4) * 6, skeletonColours, GL_STREAM_DRAW); glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 0, 0); glEnableVertexAttribArray(1); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, 0); glLineWidth(2.0f); glDrawArrays(GL_LINES, 0, currentSkeleton.numJoints * 6); // draw Bones glLineWidth(1.0f); glBindVertexArray(0); //Delete the VBO and VAO, and the heap memory we allocated earlier glDeleteVertexArrays(1, &skeletonArray); glDeleteBuffers(1, &skeletonBuffer); glDeleteBuffers(1, &skeletonColourBuffer); delete[]skeletonVertices; delete[]skeletonColours; }