virtual void createCollisionObjectGraphicsObject(btCollisionObject* obj, const btVector3& color)
	{
		OpenGLGuiHelper::createCollisionObjectGraphicsObject(obj, color);
		int colIndex = obj->getUserIndex();
		int shapeIndex = obj->getCollisionShape()->getUserIndex();

		if (colIndex >= 0 && shapeIndex >= 0)
		{
			m_swInstances.insert(colIndex, shapeIndex);
		}
	}
	virtual int registerGraphicsShape(const float* vertices, int numvertices, const int* indices, int numIndices, int primitiveType, int textureId)
	{
		int shapeIndex = OpenGLGuiHelper::registerGraphicsShape(vertices, numvertices, indices, numIndices, primitiveType, textureId);
		if (shapeIndex >= 0)
		{
			TinyRenderObjectData* swObj = new TinyRenderObjectData(m_rgbColorBuffer, m_depthBuffer);
			float rgbaColor[4] = {1, 1, 1, 1};
			swObj->registerMeshShape(vertices, numvertices, indices, numIndices, rgbaColor);
			//swObj->createCube(1,1,1);//MeshShape(vertices,numvertices,indices,numIndices);
			m_swRenderObjects.insert(shapeIndex, swObj);
		}
		return shapeIndex;
	}
	virtual void createCollisionObjectGraphicsObject(btCollisionObject* obj,const btVector3& color) 
	{
		if (obj->getUserIndex()<0)
		{
			int colIndex = m_colObjUniqueIndex++;
			obj->setUserIndex(colIndex);
			int shapeIndex = obj->getCollisionShape()->getUserIndex();
		
			if (colIndex>=0 && shapeIndex>=0)
			{
				m_swInstances.insert(colIndex,shapeIndex);
			}
		}
	}
	virtual int registerGraphicsInstance(int shapeIndex, const float* position, const float* quaternion, const float* color, const float* scaling) 
	{
		int colIndex = m_colObjUniqueIndex++;
		
		if (colIndex>=0 && shapeIndex>=0)
		{
			TinyRenderObjectData** dPtr = m_swRenderObjects[shapeIndex];
            if (dPtr && *dPtr)
            {
				TinyRenderObjectData* d= *dPtr;
				d->m_localScaling.setValue(scaling[0],scaling[1],scaling[2]);
				m_swInstances.insert(colIndex,shapeIndex);
			}
		}
		
		return colIndex;
	}
	virtual int registerGraphicsShape(const float* vertices, int numvertices, const int* indices, int numIndices,int primitiveType, int textureId)
	{
		int shapeIndex = m_swRenderObjects.size();

		TinyRenderObjectData* swObj = new TinyRenderObjectData(m_rgbColorBuffer,m_depthBuffer);
        float rgbaColor[4] = {1,1,1,1};

		//if (textureId>=0)
		//{
		//	swObj->registerMeshShape(vertices,numvertices,indices,numIndices,rgbaColor);
		//} else
		{
			swObj->registerMeshShape(vertices,numvertices,indices,numIndices,rgbaColor);
		}
		//swObj->createCube(1,1,1);//MeshShape(vertices,numvertices,indices,numIndices);
        m_swRenderObjects.insert(shapeIndex,swObj);
		return shapeIndex;
	}
void readLibraryGeometries(TiXmlDocument& doc, btAlignedObjectArray<GLInstanceGraphicsShape>& visualShapes, btHashMap<btHashString,int>& name2Shape, float extraScaling) 
{
	btHashMap<btHashString,TiXmlElement* > allSources;
	btHashMap<btHashString,VertexSource> vertexSources;
	for(TiXmlElement* geometry = doc.RootElement()->FirstChildElement("library_geometries")->FirstChildElement("geometry");
			geometry != NULL; geometry = geometry->NextSiblingElement("geometry")) 
	{
		btAlignedObjectArray<btVector3> vertexPositions;
		btAlignedObjectArray<btVector3> vertexNormals;
		btAlignedObjectArray<int> indices;

		const char* geometryName = geometry->Attribute("id");
		for (TiXmlElement* mesh = geometry->FirstChildElement("mesh");(mesh != NULL); mesh = mesh->NextSiblingElement("mesh")) 
		{
			TiXmlElement* vertices2 = mesh->FirstChildElement("vertices");
			
			for (TiXmlElement* source = mesh->FirstChildElement("source");source != NULL;source = source->NextSiblingElement("source")) 
			{
				const char* srcId= source->Attribute("id");
//				printf("source id=%s\n",srcId);
				allSources.insert(srcId,source);
			}
			const char* vertexId = vertices2->Attribute("id");
			//printf("vertices id=%s\n",vertexId);
			VertexSource vs;
			for(TiXmlElement* input = vertices2->FirstChildElement("input");input != NULL;input = input->NextSiblingElement("input")) 
			{
				const char* sem = input->Attribute("semantic");
				std::string semName(sem);
//					printf("sem=%s\n",sem);
				const char* src = input->Attribute("source");
//					printf("src=%s\n",src);
				const char* srcIdRef = input->Attribute("source");
				std::string source_name;
				source_name = std::string(srcIdRef);
				source_name = source_name.erase(0, 1);
				if (semName=="POSITION")
				{
					vs.m_positionArrayId = source_name;
				}
				if (semName=="NORMAL")
				{
					vs.m_normalArrayId = source_name;
				}
			}
			vertexSources.insert(vertexId,vs);

			for (TiXmlElement* primitive = mesh->FirstChildElement("triangles"); primitive; primitive = primitive->NextSiblingElement("triangles"))
			{
				std::string positionSourceName;
				std::string normalSourceName;
				int primitiveCount;
				primitive->QueryIntAttribute("count", &primitiveCount);
				bool positionAndNormalInVertex=false;
				int indexStride=1;
				int posOffset = 0;
				int normalOffset = 0;
				int numIndices = 0;
				{
					for (TiXmlElement* input = primitive->FirstChildElement("input");input != NULL;input = input->NextSiblingElement("input")) 
					{
						const char* sem = input->Attribute("semantic");
						std::string semName(sem);
						int offset = atoi(input->Attribute("offset"));
						if ((offset+1)>indexStride)
							indexStride=offset+1;
						//printf("sem=%s\n",sem);
						const char* src = input->Attribute("source");
						//printf("src=%s\n",src);
						const char* srcIdRef = input->Attribute("source");
						std::string source_name;
						source_name = std::string(srcIdRef);
						source_name = source_name.erase(0, 1);
							
						if (semName=="VERTEX")
						{
							//now we have POSITION and possibly NORMAL too, using same index array (<p>)
							VertexSource* vs = vertexSources[source_name.c_str()];
							if (vs->m_positionArrayId.length())
							{
								positionSourceName = vs->m_positionArrayId;
								posOffset = offset;
							}
							if (vs->m_normalArrayId.length())
							{
								normalSourceName = vs->m_normalArrayId;
								normalOffset  = offset;
								positionAndNormalInVertex = true;
							}
						}
						if (semName=="NORMAL")
						{
							btAssert(normalSourceName.length()==0);
							normalSourceName = source_name;
							normalOffset  = offset;
							positionAndNormalInVertex = false;
						}
					}
					numIndices = primitiveCount * 3; 
				}
				btAlignedObjectArray<float> positionFloatArray;
				int posStride=1;
				TiXmlElement** sourcePtr = allSources[positionSourceName.c_str()];
				if (sourcePtr)
				{
					readFloatArray(*sourcePtr,positionFloatArray, posStride);
				}
				btAlignedObjectArray<float> normalFloatArray;
				int normalStride=1;
				sourcePtr = allSources[normalSourceName.c_str()];
				if (sourcePtr)
				{
					readFloatArray(*sourcePtr,normalFloatArray,normalStride);
				}
				btAlignedObjectArray<int> curIndices;
				curIndices.reserve(numIndices*indexStride);
				TokenIntArray adder(curIndices);
				tokenize(primitive->FirstChildElement("p")->GetText(),adder);
				assert(curIndices.size() == numIndices*indexStride);
				int indexOffset = vertexPositions.size();

				for(int index=0; index<numIndices; index++) 
				{
					int posIndex = curIndices[index*indexStride+posOffset];
					int normalIndex = curIndices[index*indexStride+normalOffset];
					vertexPositions.push_back(btVector3(extraScaling*positionFloatArray[posIndex*3+0],
						extraScaling*positionFloatArray[posIndex*3+1],
						extraScaling*positionFloatArray[posIndex*3+2]));
							
					if (normalFloatArray.size() && (normalFloatArray.size()>normalIndex))
					{
						vertexNormals.push_back(btVector3(normalFloatArray[normalIndex*3+0],
															normalFloatArray[normalIndex*3+1],
															normalFloatArray[normalIndex*3+2]));
					} else
					{
						//add a dummy normal of length zero, so it is easy to detect that it is an invalid normal
						vertexNormals.push_back(btVector3(0,0,0));
					}
				}
				int curNumIndices = indices.size();
				indices.resize(curNumIndices+numIndices);
				for(int index=0; index<numIndices; index++) 
				{
					indices[curNumIndices+index] = index+indexOffset;
				}
			}//if(primitive != NULL) 
		}//for each mesh
		
		int shapeIndex = visualShapes.size();
		GLInstanceGraphicsShape& visualShape = visualShapes.expand();
		{
			visualShape.m_vertices = new b3AlignedObjectArray<GLInstanceVertex>;
			visualShape.m_indices = new b3AlignedObjectArray<int>;
			int indexBase = 0;

			btAssert(vertexNormals.size()==vertexPositions.size());
			for (int v=0;v<vertexPositions.size();v++)
			{
				GLInstanceVertex vtx;
				vtx.xyzw[0] = vertexPositions[v].x();
				vtx.xyzw[1] = vertexPositions[v].y();
				vtx.xyzw[2] = vertexPositions[v].z();
				vtx.xyzw[3] = 1.f;
				vtx.normal[0] = vertexNormals[v].x();
				vtx.normal[1] = vertexNormals[v].y();
				vtx.normal[2] = vertexNormals[v].z();
				vtx.uv[0] = 0.5f;
				vtx.uv[1] = 0.5f;
				visualShape.m_vertices->push_back(vtx);
			}

			for (int index=0;index<indices.size();index++)
			{
				visualShape.m_indices->push_back(indices[index]+indexBase);
			}
			
			
			printf(" index_count =%dand vertexPositions.size=%d\n",indices.size(), vertexPositions.size());
			indexBase=visualShape.m_vertices->size();
			visualShape.m_numIndices = visualShape.m_indices->size();
			visualShape.m_numvertices = visualShape.m_vertices->size();
		}
		printf("geometry name=%s\n",geometryName);
		name2Shape.insert(geometryName,shapeIndex);
		

	}//for each geometry
}
	virtual bool convertAllObjects(  bParse::btBulletFile* bulletFile2)
	{
		bool result = btBulletWorldImporter::convertAllObjects(bulletFile2);
		int i;
		//now the soft bodies
		for (i=0;i<bulletFile2->m_softBodies.size();i++)
		{
			if (bulletFile2->getFlags() & bParse::FD_DOUBLE_PRECISION)
			{
				btAssert(0); //not yet
				//btSoftBodyFloatData* softBodyData = (btSoftBodyFloatData*)bulletFile2->m_softBodies[i];
			} else
			{
				btSoftBodyFloatData* softBodyData = (btSoftBodyFloatData*)bulletFile2->m_softBodies[i];
				int i;
				int numNodes = softBodyData->m_numNodes;
				
		
				btSoftBody*		psb=new btSoftBody(&m_softRigidWorld->getWorldInfo());
				m_softBodyMap.insert(softBodyData,psb);

				//materials
				for (i=0;i<softBodyData->m_numMaterials;i++)
				{
					SoftBodyMaterialData* matData = softBodyData->m_materials[i];
					btSoftBody::Material** matPtr = m_materialMap.find(matData);
					btSoftBody::Material* mat = 0;
					if (matPtr&& *matPtr)
					{
						mat = *matPtr;
					} else
					{
						mat = psb->appendMaterial();
						mat->m_flags = matData->m_flags;
						mat->m_kAST = matData->m_angularStiffness;
						mat->m_kLST = matData->m_linearStiffness;
						mat->m_kVST = matData->m_volumeStiffness;
						m_materialMap.insert(matData,mat);
					}
				}




				for (i=0;i<numNodes;i++)
				{
					SoftBodyNodeData& nodeData = softBodyData->m_nodes[i];
					btVector3 position;
					position.deSerializeFloat(nodeData.m_position);
					btScalar mass = nodeData.m_inverseMass? 1./nodeData.m_inverseMass : 0.f;
					psb->appendNode(position,mass);
					btSoftBody::Node* node = &psb->m_nodes[psb->m_nodes.size()-1];
					node->m_area = nodeData.m_area;
					node->m_battach = nodeData.m_attach;
					node->m_f.deSerializeFloat(nodeData.m_accumulatedForce);
					node->m_im = nodeData.m_inverseMass;

					btSoftBody::Material** matPtr = m_materialMap.find(nodeData.m_material);
					if (matPtr && *matPtr)
					{
						node->m_material = *matPtr;
					} else
					{
						printf("no mat?\n");
					}
					
					node->m_n.deSerializeFloat(nodeData.m_normal);
					node->m_q = node->m_x;
					node->m_v.deSerializeFloat(nodeData.m_velocity);
					
				}

				for (i=0;i<softBodyData->m_numLinks;i++)
				{
					SoftBodyLinkData& linkData = softBodyData->m_links[i];
					btSoftBody::Material** matPtr = m_materialMap.find(linkData.m_material);
					if (matPtr && *matPtr)
					{
						psb->appendLink(linkData.m_nodeIndices[0],linkData.m_nodeIndices[1],*matPtr);
					} else
					{
						psb->appendLink(linkData.m_nodeIndices[0],linkData.m_nodeIndices[1]);
					}
					btSoftBody::Link* link = &psb->m_links[psb->m_links.size()-1];
					link->m_bbending = linkData.m_bbending;
					link->m_rl = linkData.m_restLength;
				}

				for (i=0;i<softBodyData->m_numFaces;i++)
				{
					SoftBodyFaceData& faceData = softBodyData->m_faces[i];
					btSoftBody::Material** matPtr = m_materialMap.find(faceData.m_material);
					if (matPtr && *matPtr)
					{
						psb->appendFace(faceData.m_nodeIndices[0],faceData.m_nodeIndices[1],faceData.m_nodeIndices[2],*matPtr);
					} else
					{
						psb->appendFace(faceData.m_nodeIndices[0],faceData.m_nodeIndices[1],faceData.m_nodeIndices[2]);
					}
					btSoftBody::Face* face = &psb->m_faces[psb->m_faces.size()-1];
					face->m_normal.deSerializeFloat(faceData.m_normal);
					face->m_ra = faceData.m_restArea;
				}

			

				//anchors
				for (i=0;i<softBodyData->m_numAnchors;i++)
				{
					btCollisionObject** colAptr = m_bodyMap.find(softBodyData->m_anchors[i].m_rigidBody);
					if (colAptr && *colAptr)
					{
						btRigidBody* body = btRigidBody::upcast(*colAptr);
						if (body)
						{
							bool disableCollision = false;
							btVector3 localPivot;
							localPivot.deSerializeFloat(softBodyData->m_anchors[i].m_localFrame);
							psb->appendAnchor(softBodyData->m_anchors[i].m_nodeIndex,body,localPivot, disableCollision);
						}
					}
				}

				if (softBodyData->m_pose)
				{
					psb->m_pose.m_aqq.deSerializeFloat(  softBodyData->m_pose->m_aqq);
					psb->m_pose.m_bframe = (softBodyData->m_pose->m_bframe!=0);
					psb->m_pose.m_bvolume = (softBodyData->m_pose->m_bvolume!=0);
					psb->m_pose.m_com.deSerializeFloat(softBodyData->m_pose->m_com);
					
					psb->m_pose.m_pos.resize(softBodyData->m_pose->m_numPositions);
					for (i=0;i<softBodyData->m_pose->m_numPositions;i++)
					{
						psb->m_pose.m_pos[i].deSerializeFloat(softBodyData->m_pose->m_positions[i]);
					}
					psb->m_pose.m_rot.deSerializeFloat(softBodyData->m_pose->m_rot);
					psb->m_pose.m_scl.deSerializeFloat(softBodyData->m_pose->m_scale);
					psb->m_pose.m_wgh.resize(softBodyData->m_pose->m_numWeigts);
					for (i=0;i<softBodyData->m_pose->m_numWeigts;i++)
					{
						psb->m_pose.m_wgh[i] = softBodyData->m_pose->m_weights[i];
					}
					psb->m_pose.m_volume = softBodyData->m_pose->m_restVolume;
				}

#if 1
				psb->m_cfg.piterations=softBodyData->m_config.m_positionIterations;
				psb->m_cfg.diterations=softBodyData->m_config.m_driftIterations;
				psb->m_cfg.citerations=softBodyData->m_config.m_clusterIterations;
				psb->m_cfg.viterations=softBodyData->m_config.m_velocityIterations;
				
				//psb->setTotalMass(0.1);
				psb->m_cfg.aeromodel = (btSoftBody::eAeroModel::_)softBodyData->m_config.m_aeroModel;
				psb->m_cfg.kLF = softBodyData->m_config.m_lift;
				psb->m_cfg.kDG = softBodyData->m_config.m_drag;
				psb->m_cfg.kMT = softBodyData->m_config.m_poseMatch;
				psb->m_cfg.collisions = softBodyData->m_config.m_collisionFlags;
				psb->m_cfg.kDF = 1.f;//softBodyData->m_config.m_dynamicFriction;
				psb->m_cfg.kDP = softBodyData->m_config.m_damping;
				psb->m_cfg.kPR = softBodyData->m_config.m_pressure;
				psb->m_cfg.kVC = softBodyData->m_config.m_volume;
				psb->m_cfg.kAHR = softBodyData->m_config.m_anchorHardness;
				psb->m_cfg.kKHR = softBodyData->m_config.m_kineticContactHardness;
				psb->m_cfg.kSHR = softBodyData->m_config.m_softContactHardness;
				psb->m_cfg.kSRHR_CL = softBodyData->m_config.m_softRigidClusterHardness;
				psb->m_cfg.kSKHR_CL = softBodyData->m_config.m_softKineticClusterHardness;
				psb->m_cfg.kSSHR_CL = softBodyData->m_config.m_softSoftClusterHardness;
#endif

//				pm->m_kLST				=	1;

#if 1
				//clusters
				if (softBodyData->m_numClusters)
				{
					m_clusterBodyMap.insert(softBodyData->m_clusters,psb);
					int j;
					psb->m_clusters.resize(softBodyData->m_numClusters);
					for (i=0;i<softBodyData->m_numClusters;i++)
					{
						psb->m_clusters[i] = new(btAlignedAlloc(sizeof(btSoftBody::Cluster),16)) btSoftBody::Cluster();
						psb->m_clusters[i]->m_adamping = softBodyData->m_clusters[i].m_adamping;
						psb->m_clusters[i]->m_av.deSerializeFloat(softBodyData->m_clusters[i].m_av);
						psb->m_clusters[i]->m_clusterIndex = softBodyData->m_clusters[i].m_clusterIndex;
						psb->m_clusters[i]->m_collide = (softBodyData->m_clusters[i].m_collide!=0);
						psb->m_clusters[i]->m_com.deSerializeFloat(softBodyData->m_clusters[i].m_com);
						psb->m_clusters[i]->m_containsAnchor = (softBodyData->m_clusters[i].m_containsAnchor!=0);
						psb->m_clusters[i]->m_dimpulses[0].deSerializeFloat(softBodyData->m_clusters[i].m_dimpulses[0]);
						psb->m_clusters[i]->m_dimpulses[1].deSerializeFloat(softBodyData->m_clusters[i].m_dimpulses[1]);

						psb->m_clusters[i]->m_framerefs.resize(softBodyData->m_clusters[i].m_numFrameRefs);
						for (j=0;j<softBodyData->m_clusters[i].m_numFrameRefs;j++)
						{
							psb->m_clusters[i]->m_framerefs[j].deSerializeFloat(softBodyData->m_clusters[i].m_framerefs[j]);
						}
						psb->m_clusters[i]->m_nodes.resize(softBodyData->m_clusters[i].m_numNodes);
						for (j=0;j<softBodyData->m_clusters[i].m_numNodes;j++)
						{
							int nodeIndex = softBodyData->m_clusters[i].m_nodeIndices[j];
							psb->m_clusters[i]->m_nodes[j] = &psb->m_nodes[nodeIndex];
						}

						psb->m_clusters[i]->m_masses.resize(softBodyData->m_clusters[i].m_numMasses);
						for (j=0;j<softBodyData->m_clusters[i].m_numMasses;j++)
						{
							psb->m_clusters[i]->m_masses[j] = softBodyData->m_clusters[i].m_masses[j];
						}
						psb->m_clusters[i]->m_framexform.deSerializeFloat(softBodyData->m_clusters[i].m_framexform);
						psb->m_clusters[i]->m_idmass = softBodyData->m_clusters[i].m_idmass;
						psb->m_clusters[i]->m_imass = softBodyData->m_clusters[i].m_imass;
						psb->m_clusters[i]->m_invwi.deSerializeFloat(softBodyData->m_clusters[i].m_invwi);
						psb->m_clusters[i]->m_ldamping = softBodyData->m_clusters[i].m_ldamping;
						psb->m_clusters[i]->m_locii.deSerializeFloat(softBodyData->m_clusters[i].m_locii);
						psb->m_clusters[i]->m_lv.deSerializeFloat(softBodyData->m_clusters[i].m_lv);
						psb->m_clusters[i]->m_matching = softBodyData->m_clusters[i].m_matching;
						psb->m_clusters[i]->m_maxSelfCollisionImpulse = 0;//softBodyData->m_clusters[i].m_maxSelfCollisionImpulse;
						psb->m_clusters[i]->m_ndamping = softBodyData->m_clusters[i].m_ndamping;
						psb->m_clusters[i]->m_ndimpulses = softBodyData->m_clusters[i].m_ndimpulses;
						psb->m_clusters[i]->m_nvimpulses = softBodyData->m_clusters[i].m_nvimpulses;
						psb->m_clusters[i]->m_selfCollisionImpulseFactor = softBodyData->m_clusters[i].m_selfCollisionImpulseFactor;
						psb->m_clusters[i]->m_vimpulses[0].deSerializeFloat(softBodyData->m_clusters[i].m_vimpulses[0]);
						psb->m_clusters[i]->m_vimpulses[1].deSerializeFloat(softBodyData->m_clusters[i].m_vimpulses[1]);
						
					}
					//psb->initializeClusters();
					//psb->updateClusters();

				}
#else

				psb->m_cfg.piterations	=	2;
				psb->m_cfg.collisions	=	btSoftBody::fCollision::CL_SS+	btSoftBody::fCollision::CL_RS;
				//psb->setTotalMass(50,true);
				//psb->generateClusters(64);
				//psb->m_cfg.kDF=1;
				psb->generateClusters(8);


#endif //



				psb->updateConstants();
				m_softRigidWorld->getWorldInfo().m_dispatcher = m_softRigidWorld->getDispatcher();
				
				m_softRigidWorld->addSoftBody(psb);


			}
		}


		//now the soft body joints
		for (i=0;i<bulletFile2->m_softBodies.size();i++)
		{
			if (bulletFile2->getFlags() & bParse::FD_DOUBLE_PRECISION)
			{
				btAssert(0); //not yet
				//btSoftBodyFloatData* softBodyData = (btSoftBodyFloatData*)bulletFile2->m_softBodies[i];
			} else
			{
				btSoftBodyFloatData* softBodyData = (btSoftBodyFloatData*)bulletFile2->m_softBodies[i];
				btSoftBody** sbp = m_softBodyMap.find(softBodyData);
				if (sbp && *sbp)
				{
					btSoftBody* sb = *sbp;
					for (int i=0;i<softBodyData->m_numJoints;i++)
					{
						btSoftBodyJointData* sbjoint = &softBodyData->m_joints[i];


						btSoftBody::Body bdyB;

						btSoftBody* sbB = 0;
						btTransform transA;
						transA.setIdentity();
						transA = sb->m_clusters[0]->m_framexform;

						btCollisionObject** colBptr = m_bodyMap.find(sbjoint->m_bodyB);
						if (colBptr && *colBptr)
						{
							btRigidBody* rbB = btRigidBody::upcast(*colBptr);
							if (rbB)
							{
								bdyB = rbB;
							} else
							{
								bdyB = *colBptr;
							}
						}


						btSoftBody** bodyBptr = m_clusterBodyMap.find(sbjoint->m_bodyB);
						if (bodyBptr && *bodyBptr )
						{
							sbB = *bodyBptr;
							bdyB = sbB->m_clusters[0];
						}


						if (sbjoint->m_jointType==btSoftBody::Joint::eType::Linear)
						{
							btSoftBody::LJoint::Specs specs;
							specs.cfm = sbjoint->m_cfm;
							specs.erp = sbjoint->m_erp;
							specs.split = sbjoint->m_split;
							btVector3 relA;
							relA.deSerializeFloat(sbjoint->m_refs[0]);
							specs.position = transA*relA;
							sb->appendLinearJoint(specs,sb->m_clusters[0],bdyB);
						}

						if (sbjoint->m_jointType==btSoftBody::Joint::eType::Angular)
						{
							btSoftBody::AJoint::Specs specs;
							specs.cfm = sbjoint->m_cfm;
							specs.erp = sbjoint->m_erp;
							specs.split = sbjoint->m_split;
							btVector3 relA;
							relA.deSerializeFloat(sbjoint->m_refs[0]);
							specs.axis = transA.getBasis()*relA;
							sb->appendAngularJoint(specs,sb->m_clusters[0],bdyB);
						}
					}
				}

			}
		}

		return result;

	}
Exemple #8
0
	//after each object is converter, including collision object, create a graphics object (and bind them)
	virtual void createGraphicsObject(_bObj* tmpObject, class btCollisionObject* bulletObject)
	{
		btRigidBody* body = btRigidBody::upcast(bulletObject);

		btRenderMesh* mesh = 0;
		if (tmpObject->data.mesh && tmpObject->data.mesh->vert_count && tmpObject->data.mesh->face_count)
		{
			if (tmpObject->data.mesh->vert_count> 16300)
			{
				printf("tmpObject->data.mesh->vert_count = %d\n",tmpObject->data.mesh->vert_count);
				
			}


			mesh = new btRenderMesh();
			mesh->m_bulletObject = bulletObject;

			btAlignedObjectArray<btVector3> originalVertices;
			originalVertices.resize(tmpObject->data.mesh->vert_count);

			for (int v=0;v<tmpObject->data.mesh->vert_count;v++)
			{
				float* vt3 = tmpObject->data.mesh->vert[v].xyz;
				originalVertices[v].setValue( IRR_X_M*vt3[IRR_X],IRR_Y_M*vt3[IRR_Y],IRR_Z_M*vt3[IRR_Z]);
			}
			int numVertices = 0;
			int numTriangles=0;
			int currentIndex=0;
			btTexVert* texVert = 0;
			

			for (int t=0;t<tmpObject->data.mesh->face_count;t++)
			{
				
				int originalIndex = tmpObject->data.mesh->face[t].v[IRR_TRI_0_X];
				mesh->m_indices.push_back(currentIndex);
				texVert = &mesh->m_vertices.expand();
				texVert->m_localxyz = originalVertices[originalIndex];
				texVert->m_uv1[0] = tmpObject->data.mesh->face[t].uv[IRR_TRI_0_X][0];
				texVert->m_uv1[1] = tmpObject->data.mesh->face[t].uv[IRR_TRI_0_X][1];
				numVertices++;
				currentIndex++;

				originalIndex = tmpObject->data.mesh->face[t].v[IRR_TRI_0_Y];
				mesh->m_indices.push_back(currentIndex);
				texVert = &mesh->m_vertices.expand();
				texVert->m_localxyz = originalVertices[originalIndex];
				texVert->m_uv1[0] = tmpObject->data.mesh->face[t].uv[IRR_TRI_0_Y][0];
				texVert->m_uv1[1] = tmpObject->data.mesh->face[t].uv[IRR_TRI_0_Y][1];
				numVertices++;
				currentIndex++;

				originalIndex = tmpObject->data.mesh->face[t].v[IRR_TRI_0_Z];
				mesh->m_indices.push_back(currentIndex);
				texVert = &mesh->m_vertices.expand();
				texVert->m_localxyz = originalVertices[originalIndex];
				texVert->m_uv1[0] = tmpObject->data.mesh->face[t].uv[IRR_TRI_0_Z][0];
				texVert->m_uv1[1] = tmpObject->data.mesh->face[t].uv[IRR_TRI_0_Z][1];
				numVertices++;
				currentIndex++;
				numTriangles++;

				if (tmpObject->data.mesh->face[t].v[3])
				{
					originalIndex = tmpObject->data.mesh->face[t].v[IRR_TRI_1_X];
					mesh->m_indices.push_back(currentIndex);
					texVert = &mesh->m_vertices.expand();
					texVert->m_localxyz = originalVertices[originalIndex];
					texVert->m_uv1[0] = tmpObject->data.mesh->face[t].uv[IRR_TRI_1_X][0];
					texVert->m_uv1[1] = tmpObject->data.mesh->face[t].uv[IRR_TRI_1_X][1];
					numVertices++;
					currentIndex++;

					originalIndex = tmpObject->data.mesh->face[t].v[IRR_TRI_1_Y];
					mesh->m_indices.push_back(currentIndex);
					texVert = &mesh->m_vertices.expand();
					texVert->m_localxyz = originalVertices[originalIndex];
					texVert->m_uv1[0] = tmpObject->data.mesh->face[t].uv[IRR_TRI_1_Y][0];
					texVert->m_uv1[1] = tmpObject->data.mesh->face[t].uv[IRR_TRI_1_Y][1];
					numVertices++;
					currentIndex++;

					originalIndex = tmpObject->data.mesh->face[t].v[IRR_TRI_1_Z];
					mesh->m_indices.push_back(currentIndex);
					texVert = &mesh->m_vertices.expand();
					texVert->m_localxyz = originalVertices[originalIndex];
					texVert->m_uv1[0] = tmpObject->data.mesh->face[t].uv[IRR_TRI_1_Z][0];
					texVert->m_uv1[1] = tmpObject->data.mesh->face[t].uv[IRR_TRI_1_Z][1];
					numVertices++;
					numTriangles++;
					currentIndex++;
				}
			}

			if (numTriangles>0)
			{
				m_renderMeshes.push_back(mesh);
				printf("numTris = %d\n",numTriangles);
				//scene::ISceneNode* node = createMeshNode(mesh->m_vertices,numVertices,indices,numIndices,numTriangles,bulletObject,tmpObject);
				//if (newMotionState && node)
				//	newMotionState->addIrrlichtNode(node);

			}
		}

		if (tmpObject->data.mesh->face[0].m_image)
		{
			const char* fileName = tmpObject->data.mesh->face[0].m_image->m_imagePathName;
			
			BasicTexture* texture0 = findTexture(fileName);

			if (!texture0)
			{
				void* jpgData = tmpObject->data.mesh->face[0].m_image->m_packedImagePtr;
				int jpgSize = tmpObject->data.mesh->face[0].m_image->m_sizePackedImage;
				if (jpgSize)
				{
					texture0 = new BasicTexture((unsigned char*)jpgData,jpgSize);
					printf("texture filename=%s\n",fileName);
					texture0->loadTextureMemory(fileName);

					m_textures.insert(fileName,texture0);
					

				}
			}

			if (texture0 && mesh)
			{
				mesh->m_texture = texture0;
			}
		}
	}