void dgCollisionUserMesh::GetCollisionInfo(dgCollisionInfo* info) const { dgCollision::GetCollisionInfo(info); info->m_offsetMatrix = GetOffsetMatrix(); if (m_getInfo) { m_getInfo (m_userData, info); } }
void dgCollisionCone::GetCollisionInfo(dgCollisionInfo* info) const { dgCollisionConvex::GetCollisionInfo(info); info->m_cone.m_r = m_radius; info->m_cone.m_height = m_height * dgFloat32 (2.0f); info->m_offsetMatrix = GetOffsetMatrix(); // strcpy (info->m_collisionType, "cone"); info->m_collisionType = m_collsionId; }
void dgCollisionChamferCylinder::GetCollisionInfo(dgCollisionInfo* info) const { dgCollisionConvex::GetCollisionInfo(info); info->m_chamferCylinder.m_r = m_radius + m_height; info->m_chamferCylinder.m_height = m_height * dgFloat32 (2.0f); info->m_offsetMatrix = GetOffsetMatrix(); // strcpy (info->m_collisionType, "chamferCylinder"); info->m_collisionType = m_collsionId; }
dgFloat32 dgCollisionCone::CalculateMassProperties (dgVector& inertia, dgVector& crossInertia, dgVector& centerOfMass) const { dgFloat32 volume; dgFloat32 inertaxx; dgFloat32 inertayyzz; //dgVector centerOfMass1; //dgVector inertia1; //dgVector crossInertia1; //volume = dgCollisionConvex::CalculateMassProperties (inertia1, crossInertia1, centerOfMass1); volume = dgFloat32 (3.1616f * 2.0f / 3.0f) * m_radius * m_radius * m_height; centerOfMass = GetOffsetMatrix().m_posit - GetOffsetMatrix().m_front.Scale (dgFloat32 (0.5f) * m_height); inertaxx = dgFloat32 (3.0f / 10.0f) * m_radius * m_radius * volume; inertayyzz = (dgFloat32 (3.0f / 20.0f) * m_radius * m_radius + dgFloat32 (4.0f / 10.0f) * m_height * m_height) * volume; dgMatrix inertiaTensor (dgGetIdentityMatrix()); inertiaTensor[0][0] = inertaxx; inertiaTensor[1][1] = inertayyzz; inertiaTensor[2][2] = inertayyzz; inertiaTensor = GetOffsetMatrix().Inverse() * inertiaTensor * GetOffsetMatrix(); crossInertia.m_x = inertiaTensor[1][2] - volume * centerOfMass.m_y * centerOfMass.m_z; crossInertia.m_y = inertiaTensor[0][2] - volume * centerOfMass.m_z * centerOfMass.m_x; crossInertia.m_z = inertiaTensor[0][1] - volume * centerOfMass.m_x * centerOfMass.m_y; dgVector central (centerOfMass.CompProduct(centerOfMass)); inertia.m_x = inertiaTensor[0][0] + volume * (central.m_y + central.m_z); inertia.m_y = inertiaTensor[1][1] + volume * (central.m_z + central.m_x); inertia.m_z = inertiaTensor[2][2] + volume * (central.m_x + central.m_y); centerOfMass = centerOfMass.Scale (volume); return volume; }
void dgCollisionConvexHull::GetCollisionInfo(dgCollisionInfo* info) const { dgCollisionConvex::GetCollisionInfo(info); info->m_offsetMatrix = GetOffsetMatrix(); // strcpy (info->m_collisionType, "convexHull"); info->m_collisionType = m_collsionId; info->m_convexHull.m_vertexCount = m_vertexCount; info->m_convexHull.m_strideInBytes = sizeof (dgVector); info->m_convexHull.m_faceCount = m_faceCount; info->m_convexHull.m_vertex = &m_vertex[0]; }
void dgCollisionCone::DebugCollision (const dgMatrix& matrixPtr, OnDebugCollisionMeshCallback callback, void* const userData) const { dgInt32 i; dgInt32 j; dgFloat32 y; dgFloat32 z; dgFloat32 angle; #define NUMBER_OF_DEBUG_SEGMENTS 24 dgTriplex pool[NUMBER_OF_DEBUG_SEGMENTS + 1]; dgTriplex face[NUMBER_OF_DEBUG_SEGMENTS]; angle = dgFloat32 (0.0f); for (i = 0; i < NUMBER_OF_DEBUG_SEGMENTS; i ++) { z = dgSin (angle) * m_radius; y = dgCos (angle) * m_radius; pool[i].m_x = - m_height; pool[i].m_y = y; pool[i].m_z = z; angle += dgPI2 / dgFloat32 (NUMBER_OF_DEBUG_SEGMENTS); } pool[i].m_x = m_height; pool[i].m_y = dgFloat32 (0.0f); pool[i].m_z = dgFloat32 (0.0f); // const dgMatrix &matrix = myBody.GetCollisionMatrix(); dgMatrix matrix (GetOffsetMatrix() * matrixPtr); matrix.TransformTriplex (pool, sizeof (dgTriplex), pool, sizeof (dgTriplex), NUMBER_OF_DEBUG_SEGMENTS + 1); j = NUMBER_OF_DEBUG_SEGMENTS - 1; for (i = 0; i < NUMBER_OF_DEBUG_SEGMENTS; i ++) { face[0] = pool[j]; face[1] = pool[i]; face[2] = pool[NUMBER_OF_DEBUG_SEGMENTS]; j = i; callback (userData, 3, &face[0].m_x, 0); } for (i = 0; i < NUMBER_OF_DEBUG_SEGMENTS; i ++) { face[i] = pool[NUMBER_OF_DEBUG_SEGMENTS - 1 - i]; } callback (userData, NUMBER_OF_DEBUG_SEGMENTS, &face[0].m_x, 0); }
void dgCollisionBVH::GetCollisionInfo(dgCollisionInfo* info) const { dgCollision::GetCollisionInfo(info); info->m_offsetMatrix = GetOffsetMatrix(); info->m_collisionType = m_collsionId; dgGetVertexListIndexList data; data.m_indexList = NULL; data.m_userDataList = NULL; data.m_maxIndexCount = 1000000000; data.m_triangleCount = 0; dgVector p0 (-1.0e10f, -1.0e10f, -1.0e10f, 1.0f); dgVector p1 ( 1.0e10f, 1.0e10f, 1.0e10f, 1.0f); ForAllSectors (p0, p1, GetTriangleCount, &data); info->m_bvhCollision.m_vertexCount = GetVertexCount(); info->m_bvhCollision.m_indexCount = data.m_triangleCount * 3; }
void dgCollisionConvexHull::DebugCollision (const dgMatrix& matrixPtr, OnDebugCollisionMeshCallback callback, void* const userData) const { dgInt32 i; dgInt32 count; dgConvexSimplexEdge *ptr; dgConvexSimplexEdge *face; dgStack<dgTriplex> tmp (m_vertexCount); dgMatrix matrix (GetOffsetMatrix() * matrixPtr); matrix.TransformTriplex (&tmp[0].m_x, sizeof (dgTriplex), &m_vertex[0].m_x, sizeof (dgVector), m_vertexCount); for (i = 0; i < m_faceCount; i ++) { face = m_faceArray[i]; ptr = face; count = 0; dgTriplex vertex[256]; do { vertex[count] = tmp[ptr->m_vertex]; count ++; ptr = ptr->m_next; } while (ptr != face); callback (userData, count, &vertex[0].m_x, 0); } }
void dgCollisionChamferCylinder::DebugCollision (const dgMatrix& matrixPtr, OnDebugCollisionMeshCallback callback, void* const userData) const { dgInt32 i; dgInt32 j; dgInt32 index; dgInt32 index0; dgInt32 brakes; dgInt32 slices; dgFloat32 sliceStep; dgFloat32 sliceAngle; dgFloat32 breakStep; dgFloat32 breakAngle; slices = 12; brakes = 24; sliceAngle = dgFloat32 (0.0f); breakAngle = dgFloat32 (0.0f); sliceStep = dgPI / slices; breakStep = dgPI2 / brakes; dgTriplex pool[24 * (12 + 1)]; dgMatrix rot (dgPitchMatrix (breakStep)); index = 0; for (j = 0; j <= slices; j ++) { dgVector p0 (-m_height * dgCos(sliceAngle), dgFloat32 (0.0f), m_radius + m_height * dgSin(sliceAngle), dgFloat32 (0.0f)); sliceAngle += sliceStep; for (i = 0; i < brakes; i ++) { pool[index].m_x = p0.m_x; pool[index].m_y = p0.m_y; pool[index].m_z = p0.m_z; index ++; p0 = rot.UnrotateVector (p0); } } // const dgMatrix &matrix = myBody.GetCollisionMatrix(); dgMatrix matrix (GetOffsetMatrix() * matrixPtr); matrix.TransformTriplex (&pool[0].m_x, sizeof (dgTriplex), &pool[0].m_x, sizeof (dgTriplex), 24 * (12 + 1)); dgTriplex face[32]; index = 0; for (j = 0; j < slices; j ++) { index0 = index + brakes - 1; for (i = 0; i < brakes; i ++) { face[0] = pool[index]; face[1] = pool[index0]; face[2] = pool[index0 + brakes]; face[3] = pool[index + brakes]; index0 = index; index ++; callback (userData, 4, &face[0].m_x, 0); } } for (i = 0; i < brakes; i ++) { face[i] = pool[i]; } callback (userData, 24, &face[0].m_x, 0); for (i = 0; i < brakes; i ++) { face[i] = pool[brakes * (slices + 1) - i - 1]; } callback (userData, 24, &face[0].m_x, 0); }
void ModelDefinition::Serialize(Serializer &serializer) const { BasicSerializer intermediarySerializer; ///////////////////////////////////// // Bones intermediarySerializer.Write(static_cast<uint32_t>(m_bones.count)); // Local information. for (size_t iBone = 0; iBone < m_bones.count; ++iBone) { auto bone = m_bones[iBone]; assert(bone != nullptr); { // Name. intermediarySerializer.WriteString(bone->GetName()); // Relative transformation. intermediarySerializer.Write(bone->GetPosition()); intermediarySerializer.Write(bone->GetRotation()); intermediarySerializer.Write(bone->GetScale()); // 4x4 offset matrix. intermediarySerializer.Write(bone->GetOffsetMatrix()); } } // Parents. -1 for bones without parents. for (size_t iBone = 0; iBone < m_bones.count; ++iBone) { auto bone = m_bones[iBone]; assert(bone != nullptr); { auto parentBone = bone->GetParent(); if (parentBone != nullptr) { size_t parentBoneIndex; if (!this->FindBoneIndex(parentBone, parentBoneIndex)) { assert(false); } intermediarySerializer.Write(static_cast<uint32_t>(parentBoneIndex)); } else { intermediarySerializer.Write(static_cast<uint32_t>(-1)); } } } Serialization::ChunkHeader header; header.id = Serialization::ChunkID_Model_Bones; header.version = 1; header.sizeInBytes = intermediarySerializer.GetBufferSizeInBytes(); serializer.Write(header); serializer.Write(intermediarySerializer.GetBuffer(), header.sizeInBytes); ///////////////////////////////////// // Meshes // // Vertex data is always saved in P3T2N3T3B3 format. Bones are referenced using an integer to index into the list of bones defined above. intermediarySerializer.Clear(); intermediarySerializer.Write(static_cast<uint32_t>(this->meshes.count)); for (size_t iMesh = 0; iMesh < this->meshes.count; ++iMesh) { // Name. intermediarySerializer.WriteString(this->meshes[iMesh].name); // Material. intermediarySerializer.WriteString(this->meshes[iMesh].material->GetDefinition().relativePath); // Vertices. auto vertexArray = this->meshes[iMesh].geometry; assert(vertexArray != nullptr); { // Vertex Format. vertexArray->GetFormat().Serialize(intermediarySerializer); // Vertices. intermediarySerializer.Write(static_cast<uint32_t>(vertexArray->GetVertexCount())); if (vertexArray->GetVertexCount() > 0) { intermediarySerializer.Write(vertexArray->GetVertexDataPtr(), vertexArray->GetFormat().GetSizeInBytes() * vertexArray->GetVertexCount()); } // Indices. intermediarySerializer.Write(static_cast<uint32_t>(vertexArray->GetIndexCount())); if (vertexArray->GetIndexCount() > 0) { intermediarySerializer.Write(vertexArray->GetIndexDataPtr(), sizeof(uint32_t) * vertexArray->GetIndexCount()); } // Skinning Vertex Attributes. if (this->meshes[iMesh].skinningVertexAttributes != nullptr) { intermediarySerializer.Write(static_cast<uint32_t>(vertexArray->GetVertexCount())); if (vertexArray->GetVertexCount() > 0) { uint32_t totalBoneWeights = 0; // Bone Counts. for (size_t iVertex = 0; iVertex < vertexArray->GetVertexCount(); ++iVertex) { uint16_t count = static_cast<uint16_t>(this->meshes[iMesh].skinningVertexAttributes[iVertex].bones.count); intermediarySerializer.Write(count); totalBoneWeights += count; } // Bone/Weight Pairs. intermediarySerializer.Write(totalBoneWeights); for (size_t iVertex = 0; iVertex < vertexArray->GetVertexCount(); ++iVertex) { auto &bones = this->meshes[iMesh].skinningVertexAttributes[iVertex].bones; { for (size_t iBone = 0; iBone < bones.count; ++iBone) { auto &bone = bones[iBone]; intermediarySerializer.Write(static_cast<uint32_t>(bone.boneIndex)); intermediarySerializer.Write(static_cast<float >(bone.weight)); } } } } } else { intermediarySerializer.Write(static_cast<uint32_t>(0)); } // Default uniforms. this->meshes[iMesh].defaultUniforms.Serialize(intermediarySerializer); } } header.id = Serialization::ChunkID_Model_Meshes; header.version = 1; header.sizeInBytes = intermediarySerializer.GetBufferSizeInBytes(); serializer.Write(header); serializer.Write(intermediarySerializer.GetBuffer(), header.sizeInBytes); ///////////////////////////////////// // Animation intermediarySerializer.Clear(); intermediarySerializer.Write(static_cast<uint32_t>(m_animation.GetKeyFrameCount())); for (uint32_t iKeyFrame = 0; iKeyFrame < m_animation.GetKeyFrameCount(); ++iKeyFrame) { // Time. intermediarySerializer.Write(static_cast<float>(m_animation.GetKeyFrameTimeByIndex(iKeyFrame))); // Channels. intermediarySerializer.Write(static_cast<uint32_t>(this->animationChannelBones.count)); for (size_t iChannel = 0; iChannel < this->animationChannelBones.count; ++iChannel) { auto channel = this->animationChannelBones.buffer[iChannel]->value; auto bone = this->animationChannelBones.buffer[iChannel]->key; assert(channel != nullptr); assert(bone != nullptr); { // Bone Index. size_t boneIndex; this->FindBoneIndex(bone, boneIndex); intermediarySerializer.Write(static_cast<uint32_t>(boneIndex)); // Bone Transformation. glm::vec3 position; glm::quat rotation; glm::vec3 scale; auto key = static_cast<TransformAnimationKey*>(channel->GetKey(iKeyFrame)); if (key != nullptr) { position = key->position; rotation = key->rotation; scale = key->scale; } else { // We should never actually get here, but for completeness we'll just write identities. position = bone->GetPosition(); rotation = bone->GetRotation(); scale = bone->GetScale(); } intermediarySerializer.Write(position); intermediarySerializer.Write(rotation); intermediarySerializer.Write(scale); } } } intermediarySerializer.Write(this->animationAABBPadding); header.id = Serialization::ChunkID_Model_Animation; header.version = 1; header.sizeInBytes = intermediarySerializer.GetBufferSizeInBytes(); serializer.Write(header); serializer.Write(intermediarySerializer.GetBuffer(), header.sizeInBytes); ///////////////////////////////////// // Animation Segments intermediarySerializer.Clear(); intermediarySerializer.Write(static_cast<uint32_t>(m_animation.GetNamedSegmentCount())); for (size_t iSegment = 0; iSegment < m_animation.GetNamedSegmentCount(); ++iSegment) { auto segment = m_animation.GetNamedSegmentByIndex(iSegment); assert(segment != nullptr); { intermediarySerializer.WriteString(segment->name); intermediarySerializer.Write(static_cast<uint32_t>(segment->startKeyFrame)); intermediarySerializer.Write(static_cast<uint32_t>(segment->endKeyFrame)); } } header.id = Serialization::ChunkID_Model_AnimationSegments; header.version = 1; header.sizeInBytes = intermediarySerializer.GetBufferSizeInBytes(); serializer.Write(header); serializer.Write(intermediarySerializer.GetBuffer(), header.sizeInBytes); ///////////////////////////////////// // Animation Sequences /* intermediarySerializer.Clear(); intermediarySerializer.Write(static_cast<uint32_t>(this->animationSequences.count)); for (size_t iSequence = 0; iSequence < this->animationSequences.count; ++iSequence) { } header.id = Serialization::ChunkID_Model_AnimationSequences; header.version = 1; header.sizeInBytes = intermediarySerializer.GetBufferSizeInBytes(); serializer.Write(header); serializer.Write(intermediarySerializer.GetBuffer(), header.sizeInBytes); */ ///////////////////////////////////// // Convex Hulls intermediarySerializer.Clear(); intermediarySerializer.Write(static_cast<uint32_t>(m_convexHulls.count)); Vector<uint32_t> vertexCounts(m_convexHulls.count); Vector<uint32_t> indexCounts( m_convexHulls.count); Vector<float> vertices; Vector<uint32_t> indices; for (size_t iConvexHull = 0; iConvexHull < m_convexHulls.count; ++iConvexHull) { auto convexHull = m_convexHulls[iConvexHull]; assert(convexHull != nullptr); { uint32_t vertexCount = static_cast<uint32_t>(convexHull->GetVertexCount()); uint32_t indexCount = static_cast<uint32_t>(convexHull->GetIndexCount()); vertexCounts.PushBack(vertexCount); indexCounts.PushBack( indexCount); for (uint32_t iVertex = 0; iVertex < vertexCount; ++iVertex) { vertices.PushBack(convexHull->GetVertices()[iVertex * 3 + 0]); vertices.PushBack(convexHull->GetVertices()[iVertex * 3 + 1]); vertices.PushBack(convexHull->GetVertices()[iVertex * 3 + 2]); } for (uint32_t iIndex = 0; iIndex < indexCount; ++iIndex) { indices.PushBack(convexHull->GetIndices()[iIndex]); } } } intermediarySerializer.Write(vertexCounts.buffer, vertexCounts.count * 4); intermediarySerializer.Write(indexCounts.buffer, indexCounts.count * 4); intermediarySerializer.Write(static_cast<uint32_t>(vertices.count)); intermediarySerializer.Write(static_cast<uint32_t>(indices.count)); intermediarySerializer.Write(vertices.buffer, vertices.count * 4); intermediarySerializer.Write(indices.buffer, indices.count * 4); intermediarySerializer.Write(this->convexHullBuildSettings); header.id = Serialization::ChunkID_Model_ConvexHulls; header.version = 1; header.sizeInBytes = intermediarySerializer.GetBufferSizeInBytes(); serializer.Write(header); serializer.Write(intermediarySerializer.GetBuffer(), header.sizeInBytes); ///////////////////////////////////// // Null Chunk header.id = Serialization::ChunkID_Null; header.version = 1; header.sizeInBytes = 0; serializer.Write(header); }