void dMeshNodeInfo::BakeTransform (const dMatrix& transform) { dVector scale; dMatrix stretchMatrix; // dMatrix matrix (m_matrix * transform); // matrix.PolarDecomposition (m_matrix, scale, stretchMatrix); // matrix = dMatrix (GetIdentityMatrix(), scale, stretchMatrix); dMatrix tmp (m_matrix); dMatrix matrix (transform.Inverse4x4() * m_matrix * transform); matrix.PolarDecomposition (m_matrix, scale, stretchMatrix); matrix = transform * dMatrix (GetIdentityMatrix(), scale, stretchMatrix); int pointCount = NewtonMeshGetPointCount (m_mesh); int pointStride = NewtonMeshGetPointStrideInByte (m_mesh) / sizeof (dFloat); dFloat* const points = NewtonMeshGetPointArray (m_mesh); matrix.TransformTriplex(points, pointStride * sizeof (dFloat), points, pointStride * sizeof (dFloat), pointCount); dFloat* const normals = NewtonMeshGetNormalArray(m_mesh); dMatrix rotation (matrix.Inverse4x4().Transpose() * matrix); rotation.m_posit = dVector (0.0f, 0.0f, 0.0f, 1.0f); rotation.TransformTriplex(normals, pointStride * sizeof (dFloat), normals, pointStride * sizeof (dFloat), pointCount); int vertexCount = NewtonMeshGetVertexCount (m_mesh); int vertexStride = NewtonMeshGetVertexStrideInByte (m_mesh) / sizeof (dFloat); dFloat* const vertex = NewtonMeshGetVertexArray (m_mesh); matrix.TransformTriplex(vertex, vertexStride * sizeof (dFloat), vertex, vertexStride * sizeof (dFloat), vertexCount); }
void dMeshNodeInfo::Serialize (TiXmlElement* rootNode) const { SerialiseBase(dGeometryNodeInfo, rootNode); TiXmlElement* pointElement = new TiXmlElement ("points"); rootNode->LinkEndChild(pointElement); int bufferCount = max (NewtonMeshGetVertexCount(m_mesh), NewtonMeshGetPointCount(m_mesh)); char* buffer = new char[bufferCount * sizeof (dFloat) * 4 * 12]; dFloat* packVertex = new dFloat [4 * bufferCount]; int vertexCount = NewtonMeshGetVertexCount (m_mesh); int vertexStride = NewtonMeshGetVertexStrideInByte(m_mesh) / sizeof (dFloat); const dFloat* const vertex = NewtonMeshGetVertexArray(m_mesh); // pack the vertex Array int* vertexIndexList = new int [vertexCount]; for (int i = 0; i < vertexCount; i ++) { packVertex[i * 4 + 0] = vertex[i * vertexStride + 0]; packVertex[i * 4 + 1] = vertex[i * vertexStride + 1]; packVertex[i * 4 + 2] = vertex[i * vertexStride + 2]; packVertex[i * 4 + 3] = vertex[i * vertexStride + 3]; vertexIndexList[i] = i; } dFloatArrayToString (packVertex, vertexCount * 4, buffer, vertexCount * sizeof (dFloat) * 4 * 12); TiXmlElement* position = new TiXmlElement ("position"); pointElement->LinkEndChild(position); position->SetAttribute("float4", vertexCount); position->SetAttribute("floats", buffer); // pack the normal array int pointCount = NewtonMeshGetPointCount (m_mesh); int pointStride = NewtonMeshGetPointStrideInByte(m_mesh) / sizeof (dFloat); const dFloat* const normals = NewtonMeshGetNormalArray(m_mesh); int* normalIndexList = new int [pointCount]; for (int i = 0; i < pointCount; i ++) { packVertex[i * 3 + 0] = normals[i * pointStride + 0]; packVertex[i * 3 + 1] = normals[i * pointStride + 1]; packVertex[i * 3 + 2] = normals[i * pointStride + 2]; } int count = dPackVertexArray (packVertex, 3, 3 * sizeof (dFloat), pointCount, normalIndexList); dFloatArrayToString (packVertex, count * 3, buffer, pointCount * sizeof (dFloat) * 3 * 12); TiXmlElement* normal = new TiXmlElement ("normal"); pointElement->LinkEndChild(normal); normal->SetAttribute("float3", count); normal->SetAttribute("floats", buffer); // pack the uv0 array int* uv0IndexList = new int [pointCount]; const dFloat* const uv0s = NewtonMeshGetUV0Array(m_mesh); for (int i = 0; i < pointCount; i ++) { packVertex[i * 3 + 0] = uv0s[i * pointStride + 0]; packVertex[i * 3 + 1] = uv0s[i * pointStride + 1]; packVertex[i * 3 + 2] = 0.0f; } count = dPackVertexArray (packVertex, 3, 3 * sizeof (dFloat), pointCount, uv0IndexList); for (int i = 0; i < pointCount; i ++) { packVertex[i * 2 + 0] = packVertex[i * 3 + 0]; packVertex[i * 2 + 1] = packVertex[i * 3 + 1]; } dFloatArrayToString (packVertex, count * 2, buffer, pointCount * sizeof (dFloat) * 3 * 12); TiXmlElement* uv0 = new TiXmlElement ("uv0"); pointElement->LinkEndChild(uv0); uv0->SetAttribute("float2", count); uv0->SetAttribute("floats", buffer); // pack the uv1 array int* uv1IndexList = new int [pointCount]; const dFloat* const uv1s = NewtonMeshGetUV1Array(m_mesh); for (int i = 0; i < pointCount; i ++) { packVertex[i * 3 + 0] = uv1s[i * pointStride + 0]; packVertex[i * 3 + 1] = uv1s[i * pointStride + 1]; packVertex[i * 3 + 2] = 0.0f; } count = dPackVertexArray (packVertex, 3, 3 * sizeof (dFloat), pointCount, uv1IndexList); for (int i = 0; i < pointCount; i ++) { packVertex[i * 2 + 0] = packVertex[i * 3 + 0]; packVertex[i * 2 + 1] = packVertex[i * 3 + 1]; } dFloatArrayToString (packVertex, count * 2, buffer, pointCount * sizeof (dFloat) * 3 * 12); TiXmlElement* uv1 = new TiXmlElement ("uv1"); pointElement->LinkEndChild(uv1); uv1->SetAttribute("float2", count); uv1->SetAttribute("floats", buffer); // save the polygon array int faceCount = NewtonMeshGetTotalFaceCount (m_mesh); int indexCount = NewtonMeshGetTotalIndexCount (m_mesh); int* faceArray = new int [faceCount]; void** indexArray = new void* [indexCount]; int* materialIndexArray = new int [faceCount]; int* remapedIndexArray = new int [indexCount]; NewtonMeshGetFaces (m_mesh, faceArray, materialIndexArray, indexArray); // save the faces vertex Count dIntArrayToString (faceArray, faceCount, buffer, pointCount * sizeof (dFloat) * 3 * 12); TiXmlElement* polygons = new TiXmlElement ("polygons"); rootNode->LinkEndChild(polygons); polygons->SetAttribute("count", faceCount); polygons->SetAttribute("faceIndexCount", buffer); dIntArrayToString (materialIndexArray, faceCount, buffer, pointCount * sizeof (dFloat) * 3 * 12); TiXmlElement* faceMaterial = new TiXmlElement ("faceMaterial"); polygons->LinkEndChild(faceMaterial); faceMaterial->SetAttribute("index", buffer); for (int i = 0; i < indexCount; i ++) { // void* face = indexArray[i]; int index = NewtonMeshGetVertexIndex (m_mesh, indexArray[i]); remapedIndexArray[i] = vertexIndexList[index]; } dIntArrayToString (remapedIndexArray, indexCount, buffer, pointCount * sizeof (dFloat) * 3 * 12); TiXmlElement* positionIndex = new TiXmlElement ("position"); polygons->LinkEndChild(positionIndex); positionIndex->SetAttribute("index", buffer); for (int i = 0; i < indexCount; i ++) { // int index = indexArray[i]; int index = NewtonMeshGetPointIndex(m_mesh, indexArray[i]); remapedIndexArray[i] = normalIndexList[index]; } dIntArrayToString (remapedIndexArray, indexCount, buffer, pointCount * sizeof (dFloat) * 3 * 12); TiXmlElement* normalIndex = new TiXmlElement ("normal"); polygons->LinkEndChild(normalIndex); normalIndex->SetAttribute("index", buffer); for (int i = 0; i < indexCount; i ++) { // int index = indexArray[i]; int index = NewtonMeshGetPointIndex(m_mesh, indexArray[i]); remapedIndexArray[i] = uv0IndexList[index]; } dIntArrayToString (remapedIndexArray, indexCount, buffer, pointCount * sizeof (dFloat) * 3 * 12); TiXmlElement* uv0Index = new TiXmlElement ("uv0"); polygons->LinkEndChild(uv0Index); uv0Index->SetAttribute("index", buffer); for (int i = 0; i < indexCount; i ++) { // int index = indexArray[i]; int index = NewtonMeshGetPointIndex(m_mesh, indexArray[i]); remapedIndexArray[i] = uv1IndexList[index]; } dIntArrayToString (remapedIndexArray, indexCount, buffer, pointCount * sizeof (dFloat) * 3 * 12); TiXmlElement* uv1Index = new TiXmlElement ("uv1"); polygons->LinkEndChild(uv1Index); uv1Index->SetAttribute("index", buffer); delete[] remapedIndexArray; delete[] faceArray; delete[] indexArray; delete[] materialIndexArray; delete[] uv1IndexList; delete[] uv0IndexList; delete[] normalIndexList; delete[] vertexIndexList; delete[] packVertex; delete[] buffer; }
void Import::LoadGeometries (dScene& scene, GeometryCache& meshCache, const MaterialCache& materialCache) { dScene::Iterator iter (scene); for (iter.Begin(); iter; iter ++) { dScene::dTreeNode* const geometryNode = iter.GetNode(); dNodeInfo* const info = scene.GetInfoFromNode(geometryNode); if (info->IsType(dGeometryNodeInfo::GetRttiType())) { if (info->GetTypeId() == dMeshNodeInfo::GetRttiType()) { // add the vertices //TriObject* const geometry = CreateNewTriObject(); TriObject* const geometry = (TriObject*) CreateInstance (GEOMOBJECT_CLASS_ID, Class_ID(TRIOBJ_CLASS_ID, 0)); meshCache.AddMesh(geometry, geometryNode); dMeshNodeInfo* const meshInfo = (dMeshNodeInfo*) scene.GetInfoFromNode(geometryNode); NewtonMesh* const mesh = meshInfo->GetMesh(); NewtonMeshTriangulate (mesh); int vertexCount = NewtonMeshGetVertexCount(mesh); int pointCount = NewtonMeshGetPointCount(mesh); //int triangleCount = NewtonMeshGetTotalFaceCount(mesh); int triangleCount = 0; for (void* face = NewtonMeshGetFirstFace(mesh); face; face = NewtonMeshGetNextFace(mesh, face)) { if (!NewtonMeshIsFaceOpen(mesh, face)) { triangleCount += NewtonMeshGetFaceIndexCount (mesh, face) - 2; } } Mesh& maxMesh = geometry->mesh; maxMesh.setNumVerts(vertexCount); maxMesh.setNumFaces(triangleCount); maxMesh.setNumTVerts(pointCount); maxMesh.setNumTVFaces(triangleCount); int vertexStride = NewtonMeshGetVertexStrideInByte(mesh) / sizeof (dFloat64); dFloat64* const vertex = NewtonMeshGetVertexArray (mesh); for (int j = 0; j < vertexCount; j ++) { Point3 vx (vertex[vertexStride * j + 0], vertex[vertexStride * j + 1], vertex[vertexStride * j + 2]); maxMesh.setVert(j, vx); } int pointStride = NewtonMeshGetPointStrideInByte(mesh) / sizeof (dFloat64); dFloat64* const points = NewtonMeshGetUV0Array(mesh); for (int j = 0; j < pointCount; j ++) { Point3 uv (dFloat(points[j * pointStride + 0]), dFloat(points[j * pointStride + 1]), 0.0f); maxMesh.setTVert(j, uv); } int faceIndex = 0; for (void* face = NewtonMeshGetFirstFace(mesh); face; face = NewtonMeshGetNextFace(mesh, face)) { if (!NewtonMeshIsFaceOpen(mesh, face)) { int vertexInices[256]; int pointIndices[256]; int indexCount = NewtonMeshGetFaceIndexCount (mesh, face); int matId = NewtonMeshGetFaceMaterial (mesh, face); MaterialProxi material; material.m_mtl = 0; material.m_matID = 0; MaterialCache::dTreeNode* const materialNode = materialCache.Find(matId); if (materialNode) { material = materialNode->GetInfo(); } NewtonMeshGetFaceIndices (mesh, face, vertexInices); NewtonMeshGetFacePointIndices (mesh, face, pointIndices); for (int i = 2; i < indexCount; i ++) { Face* f = &maxMesh.faces[faceIndex]; TVFace* t = &maxMesh.tvFace[faceIndex]; f->v[0] = vertexInices[0]; f->v[1] = vertexInices[i - 1]; f->v[2] = vertexInices[i]; f->setEdgeVis(0, 1); f->setEdgeVis(1, 1); f->setEdgeVis(2, 1); f->setSmGroup(0); //f->setMatID((MtlID)matID); f->setMatID(material.m_matID); t->t[0] = pointIndices[0]; t->t[1] = pointIndices[i - 1]; t->t[2] = pointIndices[i]; faceIndex ++; } } } SetSmoothingGroups (maxMesh); #if 0 if (geom->m_uv1) { int texChannel = 2; // maxMesh.setNumMaps (texChannel, TRUE); maxMesh.setMapSupport (texChannel); if (maxMesh.mapSupport(texChannel)) { maxMesh.setNumMapVerts (texChannel, triangleCount * 3); maxMesh.setNumMapFaces (texChannel, triangleCount); UVVert *tv = maxMesh.mapVerts(texChannel); faceIndex = 0; TVFace *tf = maxMesh.mapFaces(texChannel); for (segmentPtr = geom->GetFirst(); segmentPtr; segmentPtr = segmentPtr->GetNext()) { const dSubMesh& segment = segmentPtr->GetInfo(); int triangleCount = segment.m_indexCount / 3; for (k = 0; k < triangleCount; k ++) { for (int m = 0; m < 3; m ++) { int index = segment.m_indexes[k * 3 + m]; UVVert v (dFloat (geom->m_uv1[index * 2 + 0]), dFloat (geom->m_uv1[index * 2 + 1]), 0.0f); tv[faceIndex * 3 + m] = v; tf[faceIndex].t[m] = faceIndex * 3 + m; } faceIndex ++; } } } } #endif } else { _ASSERTE (0); } } } }
void Import::LoadGeometries (dScene& scene, GeometryCache& meshCache, const MaterialCache& materialCache) { dScene::Iterator iter (scene); for (iter.Begin(); iter; iter ++) { dScene::dTreeNode* const geometryNode = iter.GetNode(); dNodeInfo* const info = scene.GetInfoFromNode(geometryNode); if (info->IsType(dGeometryNodeInfo::GetRttiType())) { if (info->GetTypeId() == dMeshNodeInfo::GetRttiType()) { // add the vertices PolyObject* const geometry = (PolyObject*) CreateInstance (GEOMOBJECT_CLASS_ID, Class_ID(POLYOBJ_CLASS_ID, 0)); meshCache.AddMesh(geometry, geometryNode); MNMesh& maxMesh = geometry->GetMesh(); dMeshNodeInfo* const meshInfo = (dMeshNodeInfo*) scene.GetInfoFromNode(geometryNode); NewtonMesh* const mesh = meshInfo->GetMesh(); //NewtonMeshTriangulate (mesh); //NewtonMeshPolygonize (mesh); int faceCount = 0; int vertexCount = NewtonMeshGetVertexCount(mesh); for (void* face = NewtonMeshGetFirstFace(mesh); face; face = NewtonMeshGetNextFace(mesh, face)) { if (!NewtonMeshIsFaceOpen(mesh, face)) { faceCount ++; } } maxMesh.Clear(); maxMesh.setNumVerts(vertexCount); maxMesh.setNumFaces(faceCount); // add all vertex int vertexStride = NewtonMeshGetVertexStrideInByte(mesh) / sizeof (dFloat64); dFloat64* const vertex = NewtonMeshGetVertexArray (mesh); for (int j = 0; j < vertexCount; j ++) { maxMesh.P(j) = Point3 (vertex[vertexStride * j + 0], vertex[vertexStride * j + 1], vertex[vertexStride * j + 2]); } // count the number of face and make a face map int faceIndex = 0; for (void* face = NewtonMeshGetFirstFace(mesh); face; face = NewtonMeshGetNextFace(mesh, face)) { if (!NewtonMeshIsFaceOpen(mesh, face)) { int faceIndices[256]; int indexCount = NewtonMeshGetFaceIndexCount (mesh, face); int matId = NewtonMeshGetFaceMaterial (mesh, face); MaterialProxi material; material.m_mtl = 0; material.m_matID = 0; MaterialCache::dTreeNode* const materialNode = materialCache.Find(matId); if (materialNode) { material = materialNode->GetInfo(); } NewtonMeshGetFaceIndices (mesh, face, faceIndices); MNFace* const face = maxMesh.F(faceIndex); face->MakePoly(indexCount, faceIndices, NULL, NULL); face->material = material.m_matID; faceIndex ++; } } int pointCount = NewtonMeshGetPointCount(mesh); int texChannels = 2; maxMesh.SetMapNum (texChannels); maxMesh.M(texChannels - 1)->ClearFlag (MN_DEAD); maxMesh.M(texChannels - 1)->setNumFaces (faceCount); maxMesh.M(texChannels - 1)->setNumVerts (pointCount); UVVert* const tv = maxMesh.M(texChannels - 1)->v; MNMapFace* const tf = maxMesh.M(texChannels - 1)->f; // add uvs dFloat64* const uv0 = NewtonMeshGetUV0Array(mesh); int pointStride = NewtonMeshGetPointStrideInByte(mesh) / sizeof (dFloat64); for (int j = 0; j < pointCount; j ++) { tv[j] = Point3 (uv0[pointStride * j + 0], uv0[pointStride * j + 1], 0.0); } faceIndex = 0; for (void* face = NewtonMeshGetFirstFace(mesh); face; face = NewtonMeshGetNextFace(mesh, face)) { if (!NewtonMeshIsFaceOpen(mesh, face)) { int faceIndices[256]; int indexCount = NewtonMeshGetFaceIndexCount (mesh, face); NewtonMeshGetFacePointIndices (mesh, face, faceIndices); MNMapFace* const textFace = &tf[faceIndex]; textFace->MakePoly (indexCount, faceIndices); faceIndex ++; } } maxMesh.InvalidateGeomCache(); maxMesh.InvalidateTopoCache(); maxMesh.FillInMesh(); } else { _ASSERTE (0); } } } }