NewtonMesh* DemoMesh::CreateNewtonMesh(NewtonWorld* const world, const dMatrix& meshMatrix) { NewtonMesh* const mesh = NewtonMeshCreate(world); NewtonMeshBeginBuild (mesh); dMatrix rotation ((meshMatrix.Inverse4x4()).Transpose4X4()); for (dListNode* node = GetFirst(); node; node = node->GetNext()) { DemoSubMesh& segment = node->GetInfo(); for (int i = 0; i < segment.m_indexCount; i += 3) { NewtonMeshBeginFace(mesh); for (int j = 0; j < 3; j ++) { int index = segment.m_indexes[i + j]; dVector p (meshMatrix.TransformVector(dVector (m_vertex[index * 3 + 0], m_vertex[index * 3 + 1], m_vertex[index * 3 + 2], 0.0f))); dVector n (rotation.RotateVector(dVector (m_normal[index * 3 + 0], m_normal[index * 3 + 1], m_normal[index * 3 + 2], 0.0f))); dAssert ((n.DotProduct3(n)) > 0.0f); n = n.Scale (1.0f / dSqrt (n.DotProduct3(n))); NewtonMeshAddPoint(mesh, p.m_x, p.m_y, p.m_z); NewtonMeshAddNormal(mesh, n.m_x, n.m_y, n.m_z); NewtonMeshAddMaterial(mesh, segment.m_textureHandle); NewtonMeshAddUV0(mesh, m_uv[index * 2 + 0], m_uv[index * 2 + 1]); } NewtonMeshEndFace(mesh); // NewtonMeshAddFace(mesh, 3, &point[0][0], sizeof (point) / 3, segment.m_textureHandle); } } NewtonMeshEndBuild(mesh); return mesh; }
NewtonMesh* CreateCollisionTreeDoubleFaces (NewtonWorld* world, NewtonCollision* optimizedDoubelFacesTree) { NewtonMesh* mesh = NewtonMeshCreate(world); dMatrix matrix (dGetIdentityMatrix()); NewtonMeshBeginFace(mesh); NewtonCollisionForEachPolygonDo (optimizedDoubelFacesTree, &matrix[0][0], ExtrudeFaces, mesh); NewtonMeshEndFace(mesh); return mesh; }
void AddTetra (NewtonMesh* const tetrahedra, int i0, int i1, int i2, int i3, const dVector* const tetra, int layer) { NewtonMeshBeginFace(tetrahedra); NewtonMeshAddPoint(tetrahedra, tetra[i0].m_x, tetra[i0].m_y, tetra[i0].m_z); NewtonMeshAddLayer(tetrahedra, layer); NewtonMeshAddPoint(tetrahedra, tetra[i1].m_x, tetra[i1].m_y, tetra[i1].m_z); NewtonMeshAddLayer(tetrahedra, layer); NewtonMeshAddPoint(tetrahedra, tetra[i2].m_x, tetra[i2].m_y, tetra[i2].m_z); NewtonMeshAddLayer(tetrahedra, layer); NewtonMeshEndFace(tetrahedra); NewtonMeshBeginFace(tetrahedra); NewtonMeshAddPoint(tetrahedra, tetra[i3].m_x, tetra[i3].m_y, tetra[i3].m_z); NewtonMeshAddLayer(tetrahedra, layer); NewtonMeshAddPoint(tetrahedra, tetra[i0].m_x, tetra[i0].m_y, tetra[i0].m_z); NewtonMeshAddLayer(tetrahedra, layer); NewtonMeshAddPoint(tetrahedra, tetra[i2].m_x, tetra[i2].m_y, tetra[i2].m_z); NewtonMeshAddLayer(tetrahedra, layer); NewtonMeshEndFace(tetrahedra); NewtonMeshBeginFace(tetrahedra); NewtonMeshAddPoint(tetrahedra, tetra[i3].m_x, tetra[i3].m_y, tetra[i3].m_z); NewtonMeshAddLayer(tetrahedra, layer); NewtonMeshAddPoint(tetrahedra, tetra[i1].m_x, tetra[i1].m_y, tetra[i1].m_z); NewtonMeshAddLayer(tetrahedra, layer); NewtonMeshAddPoint(tetrahedra, tetra[i0].m_x, tetra[i0].m_y, tetra[i0].m_z); NewtonMeshAddLayer(tetrahedra, layer); NewtonMeshEndFace(tetrahedra); NewtonMeshBeginFace(tetrahedra); NewtonMeshAddPoint(tetrahedra, tetra[i3].m_x, tetra[i3].m_y, tetra[i3].m_z); NewtonMeshAddLayer(tetrahedra, layer); NewtonMeshAddPoint(tetrahedra, tetra[i2].m_x, tetra[i2].m_y, tetra[i2].m_z); NewtonMeshAddLayer(tetrahedra, layer); NewtonMeshAddPoint(tetrahedra, tetra[i1].m_x, tetra[i1].m_y, tetra[i1].m_z); NewtonMeshAddLayer(tetrahedra, layer); NewtonMeshEndFace(tetrahedra); }
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 dMeshNodeInfo::EndBuild () { NewtonMeshEndFace(m_mesh); }
mesh::mesh(const std::string &mn, const mat4 &tf, const world &_world): /** Don't know if world() is the best thing to pass but it works for now **/ _mesh(NewtonMeshCreate(_world)) { Ogre::MeshPtr meshPtr; try { meshPtr = Ogre::MeshPtr(Ogre::MeshManager::getSingleton().load(mn, Ogre::ResourceGroupManager::AUTODETECT_RESOURCE_GROUP_NAME)); } catch(...) { return; } const Ogre::Mesh &mesh = *meshPtr; NewtonMeshBeginFace(_mesh); for (unsigned smi = 0; smi < mesh.getNumSubMeshes(); smi++) { Ogre::SubMesh *subMesh = mesh.getSubMesh(smi); Ogre::VertexData *vertexData = (subMesh->useSharedVertices) ? vertexData = mesh.sharedVertexData : vertexData = subMesh->vertexData; Ogre::VertexDeclaration *vertexDecl = vertexData->vertexDeclaration; const Ogre::VertexElement *element = vertexDecl->findElementBySemantic(Ogre::VES_POSITION); Ogre::HardwareVertexBufferSharedPtr vertexHVBSP = vertexData->vertexBufferBinding->getBuffer(element->getSource()); unsigned char *vPtr = (unsigned char*)(vertexHVBSP->lock(Ogre::HardwareBuffer::HBL_READ_ONLY)); Ogre::IndexData *indexData = subMesh->indexData; size_t numIndices = indexData->indexCount; size_t numTris = numIndices / 3; // get pointer! Ogre::HardwareIndexBufferSharedPtr indexHIBSP = indexData->indexBuffer; // 16 or 32 bit indices? bool indicesAre32Bit = (indexHIBSP->getType() == Ogre::HardwareIndexBuffer::IT_32BIT); unsigned long *longPtr = NULL; unsigned short *shortPtr = NULL; if (indicesAre32Bit) longPtr = static_cast<unsigned long*>( indexHIBSP->lock(Ogre::HardwareBuffer::HBL_READ_ONLY)); else shortPtr = static_cast<unsigned short*>( indexHIBSP->lock(Ogre::HardwareBuffer::HBL_READ_ONLY)); //now loop through the indices, getting polygon info! int iOffset = 0; for (size_t i = 0; i < numTris; i++) { vec3 triVertices[3]; unsigned char *vOffset = NULL; float *vertexPosPtr = NULL; int idx = 0; for (int j = 0; j < 3; j++) { if (indicesAre32Bit) idx = longPtr[iOffset + j]; else idx = shortPtr[iOffset + j]; vOffset = vPtr + (idx * vertexHVBSP->getVertexSize()); element->baseVertexPointerToElement(vOffset, &vertexPosPtr); triVertices[j].x = *vertexPosPtr; vertexPosPtr++; triVertices[j].y = *vertexPosPtr; vertexPosPtr++; triVertices[j].z = *vertexPosPtr; vertexPosPtr++; triVertices[j] = tf * triVertices[j]; } // _mesh, 3 vertices (triangle), (float = 4 bytes) * 3 // index = index of sub mesh (easy to recognize) NewtonMeshAddFace(_mesh, 3, &triVertices[0].x, sizeof(float) * 3, smi); iOffset += 3; } //unlock the buffers! vertexHVBSP->unlock(); indexHIBSP->unlock(); } NewtonMeshEndFace(_mesh); }