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; }
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 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); } } } }