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); }
dFloat dMeshNodeInfo::RayCast (const dVector& p0, const dVector& p1) const { dVector q0 (m_matrix.UntransformVector(p0)); dVector q1 (m_matrix.UntransformVector(p1)); // int vertexCount = NewtonMeshGetVertexCount(m_mesh); int strideInBytes = NewtonMeshGetVertexStrideInByte(m_mesh); float* const vertexList = NewtonMeshGetVertexArray(m_mesh); dFloat t = 1.2f; int xxx = 0; int xxx2 = 0; for (void* face = NewtonMeshGetFirstFace (m_mesh); face; face = NewtonMeshGetNextFace (m_mesh, face)) { if (!NewtonMeshIsFaceOpen (m_mesh, face)) { xxx ++; int indices[1024]; int vertexCount = NewtonMeshGetFaceIndexCount (m_mesh, face); NewtonMeshGetFaceIndices (m_mesh, face, indices); dFloat t1 = dPolygonRayCast (q0, q1, vertexCount, vertexList, strideInBytes, indices); if (t1 < t) { xxx2 = xxx; if (xxx2 == 40276) xxx2 = xxx; t = t1; } } } return t; }
void dMeshNodeInfo::CalcutateAABB (dVector& p0, dVector& p1) const { // int strideInBytes = NewtonMeshGetVertexStrideInByte(m_mesh); // dFloat64* const vertexList = NewtonMeshGetVertexArray(m_mesh); // dFloat t = 1.2f; // for (void* face = NewtonMeshGetFirstFace (m_mesh); face; face = NewtonMeshGetNextFace (m_mesh, face)) { // if (!NewtonMeshIsFaceOpen (m_mesh, face)) { // dMatrix matrix (GetIdentityMatrix()); // NewtonMeshCalculateOOBB(const NewtonMesh* const mesh, dFloat* const matrix, dFloat* const x, dFloat* const y, dFloat* const z); p0 = dVector (1.0e10f, 1.0e10f, 1.0e10f, 0.0f); p1 = dVector (-1.0e10f, -1.0e10f, -1.0e10f, 0.0f); int strideInBytes = NewtonMeshGetVertexStrideInByte(m_mesh); int stride = strideInBytes / sizeof (dFloat64) ; const dFloat64* const vertexList = NewtonMeshGetVertexArray(m_mesh); for (void* ptr = NewtonMeshGetFirstVertex(m_mesh); ptr; ptr = NewtonMeshGetNextVertex(m_mesh, ptr)) { int index = NewtonMeshGetVertexIndex (m_mesh, ptr); dFloat x = dFloat (vertexList[index * stride + 0]); dFloat y = dFloat (vertexList[index * stride + 1]); dFloat z = dFloat (vertexList[index * stride + 2]); dVector v (m_matrix.TransformVector(dVector (x, y, z, 0.0f))); p0[0] = dMin(v[0], p0[0]); p0[1] = dMin(v[1], p0[1]); p0[2] = dMin(v[2], p0[2]); p1[0] = dMax(v[0], p1[0]); p1[1] = dMax(v[1], p1[1]); p1[2] = dMax(v[2], p1[2]); } }
void dMeshNodeInfo::CalculateOOBBGizmo (const dMatrix& matrix, dVector& p0, dVector& p1) const { p0 = dVector ( 1.0e10f, 1.0e10f, 1.0e10f, 1.0f); p1 = dVector (-1.0e10f, -1.0e10f, -1.0e10f, 1.0f); dMatrix tranform (m_matrix * matrix) ; int stride = NewtonMeshGetVertexStrideInByte(m_mesh) / sizeof(dFloat); float* const vertexList = NewtonMeshGetVertexArray(m_mesh); for (void* vertex = NewtonMeshGetFirstVertex(m_mesh); vertex; vertex = NewtonMeshGetNextVertex(m_mesh, vertex)) { int index = NewtonMeshGetVertexIndex(m_mesh, vertex) * stride; dVector p (vertexList[index + 0], vertexList[index + 1], vertexList[index + 2], 1.0); p = tranform.TransformVector(p); p0.m_x = min (p.m_x, p0.m_x); p0.m_y = min (p.m_y, p0.m_y); p0.m_z = min (p.m_z, p0.m_z); p1.m_x = max (p.m_x, p1.m_x); p1.m_y = max (p.m_y, p1.m_y); p1.m_z = max (p.m_z, p1.m_z); } }
dFloat dMeshNodeInfo::RayCast (const dVector& q0, const dVector& q1) const { // int vertexCount = NewtonMeshGetVertexCount(m_mesh); int strideInBytes = NewtonMeshGetVertexStrideInByte(m_mesh); const dFloat64* const vertexList = NewtonMeshGetVertexArray(m_mesh); dFloat t = 1.2f; dVector p0 = m_matrix.UntransformVector(q0); dVector p1 = m_matrix.UntransformVector(q1); for (void* face = NewtonMeshGetFirstFace (m_mesh); face; face = NewtonMeshGetNextFace (m_mesh, face)) { if (!NewtonMeshIsFaceOpen (m_mesh, face)) { int indices[1024]; int vertexCount = NewtonMeshGetFaceIndexCount (m_mesh, face); NewtonMeshGetFaceIndices (m_mesh, face, indices); dFloat t1 = dPolygonRayCast (p0, p1, vertexCount, vertexList, strideInBytes, indices); if (t1 < t) { t = t1; } } } return t; }
void ConvexApproximationObject::BuildMesh() { // since max does no provide the iNode that will own this mesh I have no choice bu to apply the root matrix to all vertex ConvexApproximationClassDesc* const desc = (ConvexApproximationClassDesc*) ConvexApproximationClassDesc::GetDescriptor(); INode* const sourceNode = desc->m_sourceNode; //dMatrix rootMatrix1 (GetMatrixFromMaxMatrix (sourceNode->GetNodeTM (0))); dMatrix rootMatrix (GetMatrixFromMaxMatrix (sourceNode->GetObjectTM(0))); dVector scale; dMatrix stretchAxis; dMatrix orthogonalRootTransform; rootMatrix.PolarDecomposition (orthogonalRootTransform, scale, stretchAxis); orthogonalRootTransform = orthogonalRootTransform.Inverse(); // create a Newton world, as a manager of everything Newton related stuff NewtonWorld* const world = NewtonCreate (); // create an empty mesh and load the max mesh to it NewtonMesh* const sourceMesh = NewtonMeshCreate (world); // load all faces NewtonMeshBeginFace(sourceMesh); LoadGeometries (sourceMesh, orthogonalRootTransform); NewtonMeshEndFace(sourceMesh); // make a convex approximation form this newton mesh effect desc->m_progress = -1; Interface* const inteface = desc->m_currentInterface; inteface->ProgressStart("Creation Convex approx ...", TRUE, ConvexApproximationClassDesc::ReportMaxProgress, NULL); NewtonMesh* approximationMesh = NewtonMeshApproximateConvexDecomposition (sourceMesh, m_currentConcavity, 0.2f, m_currentMaxCount, 1000, ConvexApproximationClassDesc::ReportProgress); inteface->ProgressEnd(); NewtonMeshDestroy (sourceMesh); // now convert the new mesh to a max poly Object MNMesh& maxMesh = GetMesh(); maxMesh.ClearAndFree(); int faceCount = 0; int vertexCount = NewtonMeshGetVertexCount(approximationMesh); for (void* face = NewtonMeshGetFirstFace(approximationMesh); face; face = NewtonMeshGetNextFace(approximationMesh, face)) { if (!NewtonMeshIsFaceOpen(approximationMesh, face)) { faceCount ++; } } //maxMesh.Clear(); maxMesh.setNumVerts(vertexCount); maxMesh.setNumFaces(faceCount); // add all vertex int vertexStride = NewtonMeshGetVertexStrideInByte(approximationMesh) / sizeof (dFloat64); dFloat64* const vertex = NewtonMeshGetVertexArray (approximationMesh); for (int j = 0; j < vertexCount; j ++) { dVector p (orthogonalRootTransform.TransformVector(dVector (float (vertex[vertexStride * j + 0]), float (vertex[vertexStride * j + 1]), float (vertex[vertexStride * j + 2]), float(1.0f)))); maxMesh.P(j) = Point3 (p.m_x, p.m_y, p.m_z); } // count the number of face and make a face map int faceIndex = 0; for (void* face = NewtonMeshGetFirstFace(approximationMesh); face; face = NewtonMeshGetNextFace(approximationMesh, face)) { if (!NewtonMeshIsFaceOpen(approximationMesh, face)) { int faceIndices[256]; int indexCount = NewtonMeshGetFaceIndexCount (approximationMesh, face); NewtonMeshGetFaceIndices (approximationMesh, face, faceIndices); MNFace* const face = maxMesh.F(faceIndex); face->MakePoly(indexCount, faceIndices, NULL, NULL); face->material = 0; faceIndex ++; } } maxMesh.InvalidateGeomCache(); maxMesh.InvalidateTopoCache(); maxMesh.FillInMesh(); maxMesh.AutoSmooth(45.0f * 3.1416f / 160.0f, false, false); NewtonMeshDestroy (approximationMesh); NewtonDestroy (world); }
void BuildClothPatch (DemoEntityManager* const scene, int size_x, int size_z) { NewtonWorld* const world = scene->GetNewton(); NewtonMesh* const clothPatch = CreateQuadClothPatch(scene, size_x, size_z); // create the array of points; int vertexCount = NewtonMeshGetVertexCount(clothPatch); int stride = NewtonMeshGetVertexStrideInByte (clothPatch) / sizeof (dFloat64); const dFloat64* const meshPoints = NewtonMeshGetVertexArray (clothPatch); dVector* const points = new dVector[vertexCount]; for (int i =0; i < vertexCount; i ++ ) { points[i].m_x = dFloat (meshPoints[i * stride + 0]); points[i].m_y = dFloat (meshPoints[i * stride + 1]); points[i].m_z = dFloat (meshPoints[i * stride + 2]); points[i].m_w = 0.0f; } dFloat mass = 8.0f; // set the particle masses dFloat unitMass = mass / vertexCount; dFloat* const clothMass = new dFloat[vertexCount]; for (int i =0; i < vertexCount; i ++ ) { clothMass[i] = unitMass; } int linksCount = 0; const int maxLinkCount = size_x * size_z * 16; // create the structual constation array; dFloat structuralSpring = dAbs(mass * DEMO_GRAVITY) / 0.01f; dFloat structuralDamper = 30.0f; int* const links = new int[2 * maxLinkCount]; dFloat* const spring = new dFloat[maxLinkCount]; dFloat* const damper = new dFloat[maxLinkCount]; for (void* edgeNode = NewtonMeshGetFirstEdge (clothPatch); edgeNode; edgeNode = NewtonMeshGetNextEdge (clothPatch, edgeNode)) { int v0; int v1; NewtonMeshGetEdgeIndices (clothPatch, edgeNode, &v0, &v1); links[linksCount * 2 + 0] = v0; links[linksCount * 2 + 1] = v1; spring[linksCount] = structuralSpring; damper[linksCount] = structuralDamper; linksCount ++; dAssert (linksCount <= maxLinkCount); } // add shear constraints dFloat shearSpring = structuralSpring; dFloat shearDamper = structuralDamper; for (void* faceNode = NewtonMeshGetFirstFace (clothPatch); faceNode; faceNode = NewtonMeshGetNextFace (clothPatch, faceNode)) { if (!NewtonMeshIsFaceOpen(clothPatch, faceNode)) { int face[8]; int indexCount = NewtonMeshGetFaceIndexCount (clothPatch, faceNode); NewtonMeshGetFaceIndices (clothPatch, faceNode, face); for (int i = 2; i < indexCount - 1; i ++) { links[linksCount * 2 + 0] = face[0]; links[linksCount * 2 + 1] = face[i]; spring[linksCount] = shearSpring; damper[linksCount] = shearDamper; linksCount ++; dAssert (linksCount <= maxLinkCount); } for (int i = 3; i < indexCount; i ++) { links[linksCount * 2 + 0] = face[1]; links[linksCount * 2 + 1] = face[i]; spring[linksCount] = shearSpring; damper[linksCount] = shearDamper; linksCount ++; dAssert (linksCount <= maxLinkCount); } } } //linksCount = 0; NewtonCollision* const deformableCollision = NewtonCreateMassSpringDamperSystem(world, 0, &points[0].m_x, vertexCount, sizeof (dVector), clothMass, links, linksCount, spring, damper); m_body = CreateRigidBody(scene, mass, deformableCollision); DemoMesh* const mesh = new ClothPatchMesh (scene, clothPatch, m_body); SetMesh(mesh, dGetIdentityMatrix()); // do not forget to destroy this objects, else you get bad memory leaks. mesh->Release(); NewtonDestroyCollision(deformableCollision); NewtonMeshDestroy(clothPatch); delete[] links; delete[] damper; delete[] spring; delete[] clothMass; delete[] points; }
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; }
dCRCTYPE dLineNodeInfo::CalculateSignature() const { dCRCTYPE signature = 0; dAssert (0); #if 0 int vertexCount = NewtonMeshGetVertexCount (m_mesh); int vertexStride = NewtonMeshGetVertexStrideInByte(m_mesh); signature = dCRC64 (NewtonMeshGetVertexArray (m_mesh), vertexStride * vertexCount, signature); // for now just compare the vertex array, do no forget to add more text using the face winding and material indexed // save the polygon array int faceCount = NewtonMeshGetTotalFaceCount (mesh); int indexCount = NewtonMeshGetTotalIndexCount (mesh); int* const faceArray = new int [faceCount]; void** const indexArray = new void* [indexCount]; int* const materialIndexArray = new int [faceCount]; int* const remapedIndexArray = new int [indexCount]; NewtonMeshGetFaces (mesh, faceArray, materialIndexArray, indexArray); // save the faces vertex Count dIntArrayToString (faceArray, faceCount, buffer, bufferSizeInBytes); TiXmlElement* const polygons = new TiXmlElement ("polygons"); rootNode->LinkEndChild(polygons); polygons->SetAttribute("count", faceCount); polygons->SetAttribute("faceIndexCount", buffer); dIntArrayToString (materialIndexArray, faceCount, buffer, bufferSizeInBytes); TiXmlElement* const faceMaterial = new TiXmlElement ("faceMaterial"); polygons->LinkEndChild(faceMaterial); faceMaterial->SetAttribute("index", buffer); for (int i = 0; i < indexCount; i ++) { int index = NewtonMeshGetVertexIndex (mesh, indexArray[i]); remapedIndexArray[i] = vertexIndexList[index]; } dIntArrayToString (remapedIndexArray, indexCount, buffer, bufferSizeInBytes); TiXmlElement* const positionIndex = new TiXmlElement ("position"); polygons->LinkEndChild(positionIndex); positionIndex->SetAttribute("index", buffer); for (int i = 0; i < indexCount; i ++) { int index = NewtonMeshGetPointIndex(mesh, indexArray[i]); remapedIndexArray[i] = normalIndexList[index]; } dIntArrayToString (remapedIndexArray, indexCount, buffer, bufferSizeInBytes); TiXmlElement* const normalIndex = new TiXmlElement ("normal"); polygons->LinkEndChild(normalIndex); normalIndex->SetAttribute("index", buffer); for (int i = 0; i < indexCount; i ++) { int index = NewtonMeshGetPointIndex(mesh, indexArray[i]); remapedIndexArray[i] = uv0IndexList[index]; } dIntArrayToString (remapedIndexArray, indexCount, buffer, bufferSizeInBytes); TiXmlElement* const uv0Index = new TiXmlElement ("uv0"); polygons->LinkEndChild(uv0Index); uv0Index->SetAttribute("index", buffer); for (int i = 0; i < indexCount; i ++) { int index = NewtonMeshGetPointIndex(mesh, indexArray[i]); remapedIndexArray[i] = uv1IndexList[index]; } dIntArrayToString (remapedIndexArray, indexCount, buffer, bufferSizeInBytes); TiXmlElement* const uv1Index = new TiXmlElement ("uv1"); polygons->LinkEndChild(uv1Index); uv1Index->SetAttribute("index", buffer); #endif return signature; }
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); } } } }