Exemple #1
0
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);
}
		ClothPatchMesh(DemoEntityManager* const scene, NewtonMesh* const clothPatchMesh, NewtonBody* const body)
			:DemoMesh(clothPatchMesh, scene->GetShaderCache())
			,m_body(body)
		{
			ResetOptimization();
			//NewtonCollision* const deformableCollision = NewtonBodyGetCollision(m_body);

			int pointCount = NewtonMeshGetPointCount(clothPatchMesh);
			const int* const indexMap = NewtonMeshGetIndexToVertexMap(clothPatchMesh);
			m_indexMap = new int[pointCount];
			for (int i = 0; i < pointCount; i++) {
				int j = indexMap[i];
				m_indexMap[i] = j;
			}
		}
DemoMesh::DemoMesh(NewtonMesh* const mesh)
	:DemoMeshInterface()
	,m_uv(NULL)
	,m_vertex(NULL)
	,m_normal(NULL)
	,m_optimizedOpaqueDiplayList(0)		
	,m_optimizedTransparentDiplayList(0)
{
	// extract vertex data  from the newton mesh		
	AllocVertexData(NewtonMeshGetPointCount (mesh));

	// a valid newton mesh always has a vertex channel
	NewtonMeshGetVertexChannel(mesh, 3 * sizeof (dFloat), (dFloat*)m_vertex);
	if (NewtonMeshHasNormalChannel(mesh)) {
		NewtonMeshGetNormalChannel(mesh, 3 * sizeof (dFloat), (dFloat*)m_normal);
	}
	if (NewtonMeshHasUV0Channel(mesh)) {
		NewtonMeshGetUV0Channel(mesh, 2 * sizeof (dFloat), (dFloat*)m_uv);
	}

	// extract the materials index array for mesh
	void* const meshCookie = NewtonMeshBeginHandle (mesh); 
	for (int handle = NewtonMeshFirstMaterial (mesh, meshCookie); handle != -1; handle = NewtonMeshNextMaterial (mesh, meshCookie, handle)) {
		int textureId = NewtonMeshMaterialGetMaterial (mesh, meshCookie, handle); 
		int indexCount = NewtonMeshMaterialGetIndexCount (mesh, meshCookie, handle); 
		DemoSubMesh* const segment = AddSubMesh();

		segment->m_shiness = 1.0f;
		segment->m_ambient = dVector (0.8f, 0.8f, 0.8f, 1.0f);
		segment->m_diffuse = dVector (0.8f, 0.8f, 0.8f, 1.0f);
		segment->m_specular = dVector (0.0f, 0.0f, 0.0f, 1.0f);
		segment->m_textureHandle = textureId;

		segment->AllocIndexData (indexCount);
		// for 16 bit indices meshes
		//NewtonMeshMaterialGetIndexStreamShort (mesh, meshCookie, handle, (short int*)segment->m_indexes); 

		// for 32 bit indices mesh
		NewtonMeshMaterialGetIndexStream (mesh, meshCookie, handle, (int*)segment->m_indexes); 
	}
	NewtonMeshEndHandle (mesh, meshCookie); 

	// see if this mesh can be optimized
	OptimizeForRender ();
}
Exemple #4
0
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);
            }
        }
    }
}
DemoMesh::DemoMesh(const char* const name, const NewtonCollision* const collision, const char* const texture0, const char* const texture1, const char* const texture2, dFloat opacity, const dMatrix& uvMatrix)
	:DemoMeshInterface()
	,dList<DemoSubMesh>()
	,m_uv(NULL)
	,m_vertex(NULL)
	,m_normal(NULL)
	,m_optimizedOpaqueDiplayList(0)		
	,m_optimizedTransparentDiplayList(0)
{
	// create a helper mesh from the collision collision
	NewtonMesh* const mesh = NewtonMeshCreateFromCollision(collision);

	// apply the vertex normals
	NewtonMeshCalculateVertexNormals(mesh, 30.0f * dDegreeToRad);

	dMatrix aligmentUV(uvMatrix);
//	NewtonCollisionGetMatrix(collision, &aligmentUV[0][0]);
	aligmentUV = aligmentUV.Inverse();

	// apply uv projections
	NewtonCollisionInfoRecord info;
	NewtonCollisionGetInfo (collision, &info);
	switch (info.m_collisionType) 
	{
		case SERIALIZE_ID_SPHERE:
		{
			NewtonMeshApplySphericalMapping(mesh, LoadTexture (texture0), &aligmentUV[0][0]);
			break;
		}

		case SERIALIZE_ID_CONE:
		case SERIALIZE_ID_CAPSULE:
		case SERIALIZE_ID_CYLINDER:
		case SERIALIZE_ID_CHAMFERCYLINDER:
		{
			//NewtonMeshApplySphericalMapping(mesh, LoadTexture(texture0));
			NewtonMeshApplyCylindricalMapping(mesh, LoadTexture(texture0), LoadTexture(texture1), &aligmentUV[0][0]);
			break;
		}

		default:
		{
			int tex0 = LoadTexture(texture0);
			int tex1 = LoadTexture(texture1);
			int tex2 = LoadTexture(texture2);
			NewtonMeshApplyBoxMapping(mesh, tex0, tex1, tex2, &aligmentUV[0][0]);
			break;
		}
	}

	// extract vertex data  from the newton mesh		
	int vertexCount = NewtonMeshGetPointCount (mesh); 
	AllocVertexData(vertexCount);
	NewtonMeshGetVertexChannel(mesh, 3 * sizeof (dFloat), (dFloat*)m_vertex);
	NewtonMeshGetNormalChannel(mesh, 3 * sizeof (dFloat), (dFloat*)m_normal);
	NewtonMeshGetUV0Channel(mesh, 2 * sizeof (dFloat), (dFloat*)m_uv);

	// extract the materials index array for mesh
	void* const geometryHandle = NewtonMeshBeginHandle (mesh); 
	for (int handle = NewtonMeshFirstMaterial (mesh, geometryHandle); handle != -1; handle = NewtonMeshNextMaterial (mesh, geometryHandle, handle)) {
		int material = NewtonMeshMaterialGetMaterial (mesh, geometryHandle, handle); 
		int indexCount = NewtonMeshMaterialGetIndexCount (mesh, geometryHandle, handle); 

		DemoSubMesh* const segment = AddSubMesh();

		segment->m_textureHandle = (GLuint)material;
		segment->SetOpacity(opacity);

		segment->AllocIndexData (indexCount);
		NewtonMeshMaterialGetIndexStream (mesh, geometryHandle, handle, (int*)segment->m_indexes); 
	}
	NewtonMeshEndHandle (mesh, geometryHandle); 

	// destroy helper mesh
	NewtonMeshDestroy(mesh);

	// optimize this mesh for hardware buffers if possible
	OptimizeForRender ();
}
DemoMesh::DemoMesh(const dScene* const scene, dScene::dTreeNode* const meshNode)
	:DemoMeshInterface()
	,dList<DemoSubMesh>()
	,m_uv(NULL)
	,m_vertex(NULL)
	,m_normal(NULL)
	,m_optimizedOpaqueDiplayList(0)
	,m_optimizedTransparentDiplayList(0)
{
	dMeshNodeInfo* const meshInfo = (dMeshNodeInfo*)scene->GetInfoFromNode(meshNode);
	m_name = meshInfo->GetName();
	
	NewtonMesh* const mesh = meshInfo->GetMesh();

	// extract vertex data  from the newton mesh		
	AllocVertexData(NewtonMeshGetPointCount (mesh));
	NewtonMeshGetVertexChannel (mesh, 3 * sizeof (dFloat), (dFloat*) m_vertex);
	NewtonMeshGetNormalChannel (mesh, 3 * sizeof (dFloat), (dFloat*) m_normal);
	NewtonMeshGetUV0Channel (mesh, 2 * sizeof (dFloat), (dFloat*) m_uv);

	// bake the matrix into the vertex array
	dMatrix matrix (meshInfo->GetPivotMatrix());
	matrix.TransformTriplex(m_vertex, 3 * sizeof (dFloat), m_vertex, 3 * sizeof (dFloat), m_vertexCount);
	matrix.m_posit = dVector (0.0f, 0.0f, 0.0f, 1.0f);
	matrix = (matrix.Inverse4x4()).Transpose();
	matrix.TransformTriplex(m_normal, 3 * sizeof (dFloat), m_normal, 3 * sizeof (dFloat), m_vertexCount);

	bool hasModifiers = false;
	dTree<dScene::dTreeNode*, dCRCTYPE> materialMap;
	for (void* ptr = scene->GetFirstChildLink(meshNode); ptr; ptr = scene->GetNextChildLink (meshNode, ptr)) {
		dScene::dTreeNode* const node = scene->GetNodeFromLink(ptr);
		dNodeInfo* const info = scene->GetInfoFromNode(node);
		if (info->GetTypeId() == dMaterialNodeInfo::GetRttiType()) {
			dMaterialNodeInfo* const material = (dMaterialNodeInfo*)info;
			dCRCTYPE id = material->GetId();
			materialMap.Insert(node, id);
		} else if (info->IsType(dGeometryNodeModifierInfo::GetRttiType())) {
			hasModifiers = true;
		}
	}

	// extract the materials index array for mesh
	void* const meshCookie = NewtonMeshBeginHandle (mesh); 
	for (int handle = NewtonMeshFirstMaterial (mesh, meshCookie); handle != -1; handle = NewtonMeshNextMaterial (mesh, meshCookie, handle)) {
		int materialIndex = NewtonMeshMaterialGetMaterial (mesh, meshCookie, handle); 
		int indexCount = NewtonMeshMaterialGetIndexCount (mesh, meshCookie, handle); 
		DemoSubMesh* const segment = AddSubMesh();

		dTree<dScene::dTreeNode*, dCRCTYPE>::dTreeNode* matNodeCache = materialMap.Find(materialIndex);
		if (matNodeCache) {
			dScene::dTreeNode* const matNode = matNodeCache->GetInfo();
			dMaterialNodeInfo* const material = (dMaterialNodeInfo*) scene->GetInfoFromNode(matNode);

			if (material->GetDiffuseTextId() != -1) {
				dScene::dTreeNode* const node = scene->FindTextureByTextId(matNode, material->GetDiffuseTextId());
				dAssert (node);
				if (node) {
					dTextureNodeInfo* const texture = (dTextureNodeInfo*)scene->GetInfoFromNode(node);
					segment->m_textureHandle = LoadTexture(texture->GetPathName());
					segment->m_textureName = texture->GetPathName();
				}
			}
			segment->m_shiness = material->GetShininess();
			segment->m_ambient = material->GetAmbientColor();
			segment->m_diffuse = material->GetDiffuseColor();
			segment->m_specular = material->GetSpecularColor();
			segment->SetOpacity(material->GetOpacity());
		}

		segment->AllocIndexData (indexCount);
		// for 16 bit indices meshes
		//NewtonMeshMaterialGetIndexStreamShort (mesh, meshCookie, handle, (short int*)segment->m_indexes); 

		// for 32 bit indices mesh
		NewtonMeshMaterialGetIndexStream (mesh, meshCookie, handle, (int*)segment->m_indexes); 
	}
	NewtonMeshEndHandle (mesh, meshCookie); 

	if (!hasModifiers) {
		// see if this mesh can be optimized
		OptimizeForRender ();
	}
}