Example #1
0
FloatShapeInterval OffsetPolygonEdge::clippedEdgeXRange(float y1,
                                                        float y2) const {
  if (!overlapsYRange(y1, y2) || (y1 == maxY() && minY() <= y1) ||
      (y2 == minY() && maxY() >= y2))
    return FloatShapeInterval();

  if (isWithinYRange(y1, y2))
    return FloatShapeInterval(minX(), maxX());

  // Clip the edge line segment to the vertical range y1,y2 and then return
  // the clipped line segment's horizontal range.

  FloatPoint minYVertex;
  FloatPoint maxYVertex;
  if (vertex1().y() < vertex2().y()) {
    minYVertex = vertex1();
    maxYVertex = vertex2();
  } else {
    minYVertex = vertex2();
    maxYVertex = vertex1();
  }
  float xForY1 = (minYVertex.y() < y1) ? xIntercept(y1) : minYVertex.x();
  float xForY2 = (maxYVertex.y() > y2) ? xIntercept(y2) : maxYVertex.x();
  return FloatShapeInterval(std::min(xForY1, xForY2), std::max(xForY1, xForY2));
}
Example #2
0
bool VertexPair::overlapsRect(const FloatRect& rect) const
{
    bool boundsOverlap = (minX() < rect.maxX()) && (maxX() > rect.x()) && (minY() < rect.maxY()) && (maxY() > rect.y());
    if (!boundsOverlap)
        return false;

    float leftSideValues[4] = {
        leftSide(vertex1(), vertex2(), rect.minXMinYCorner()),
        leftSide(vertex1(), vertex2(), rect.maxXMinYCorner()),
        leftSide(vertex1(), vertex2(), rect.minXMaxYCorner()),
        leftSide(vertex1(), vertex2(), rect.maxXMaxYCorner())
    };

    int currentLeftSideSign = 0;
    for (unsigned i = 0; i < 4; ++i) {
        if (!leftSideValues[i])
            continue;
        int leftSideSign = leftSideValues[i] > 0 ? 1 : -1;
        if (!currentLeftSideSign)
            currentLeftSideSign = leftSideSign;
        else if (currentLeftSideSign != leftSideSign)
            return true;
    }

    return false;
}
Example #3
0
float OffsetPolygonEdge::xIntercept(float y) const {
  ASSERT(y >= minY() && y <= maxY());

  if (vertex1().y() == vertex2().y() || vertex1().x() == vertex2().x())
    return minX();
  if (y == minY())
    return vertex1().y() < vertex2().y() ? vertex1().x() : vertex2().x();
  if (y == maxY())
    return vertex1().y() > vertex2().y() ? vertex1().x() : vertex2().x();

  return vertex1().x() +
         ((y - vertex1().y()) * (vertex2().x() - vertex1().x()) /
          (vertex2().y() - vertex1().y()));
}
Example #4
0
// See ConvexDecompositionDemo.cpp in Bullet Docs
btCollisionShape* GameObject::GenerateShape(std::string file, float scale)
{
  ConvexDecomposition::WavefrontObj wo;
  if (!wo.loadObj (strcat ("media/models/", file.c_str ()))) {
    printf("Failed to load Player obj file\n");
  }

  btTriangleMesh* trimesh = new btTriangleMesh();

  for (int i=0;i<wo.mTriCount;i++) {
    int index0 = wo.mIndices[i*3];
    int index1 = wo.mIndices[i*3+1];
    int index2 = wo.mIndices[i*3+2];

    btVector3 vertex0(wo.mVertices[index0*3], wo.mVertices[index0*3+1],wo.mVertices[index0*3+2]);
    btVector3 vertex1(wo.mVertices[index1*3], wo.mVertices[index1*3+1],wo.mVertices[index1*3+2]);
    btVector3 vertex2(wo.mVertices[index2*3], wo.mVertices[index2*3+1],wo.mVertices[index2*3+2]);

    vertex0 *= scale;
    vertex1 *= scale;
    vertex2 *= scale;

    trimesh->addTriangle(vertex0,vertex1,vertex2);
  }

  btConvexShape* shape = new btConvexTriangleMeshShape(trimesh);

  /*printf("old numTriangles= %d\n",wo.mTriCount);
  printf("new numTrinagles= %d\n",trimesh->getNumTriangles());
  printf("old numIndices = %d\n",wo.mTriCount*3);
  printf("old numVertices = %d\n",wo.mVertexCount);*/

  return shape;
}
/* ----------------------------------------------------------------------- 
 | the function describe build btRigidBody from Ogre mesh :   
 |
 | @prama in : Ogre entity (use as a single object)
 | @pamra out : return true if build success and add collision shape to dynamicsworld
   ----------------------------------------------------------------------- */
bool
buildRigidBodyFromOgreEntity(Ogre::Entity* ent,
                             btDynamicsWorld* dynamicsWorld, 
                             btAlignedObjectArray<btCollisionShape*>& collisionShapes,
                             void* &data)
{
    void *vertices, *indices;
    size_t vertexCount = 0, indexCount = 0;
    
    getVertexBuffer(ent, vertices, vertexCount, indices, indexCount);
       
    btScalar mass(1.0f);	
    btVector3 localInertia(0,0,0);
    
    data = new btTriangleMesh();
    btTriangleMesh* trimesh = static_cast<btTriangleMesh*>(data);
    btAssert(trimesh);

    Ogre::Vector3* vert = (Ogre::Vector3*)vertices;
    Ogre::ulong* index = (Ogre::ulong*)indices;

	for (size_t i=0 ; i<vertexCount ; i++)
	{
		int index0 = index[i*3];
		int index1 = index[i*3+1];
		int index2 = index[i*3+2];

        btVector3 vertex0(vert[index0].x, vert[index0].y, vert[index0].z);
        btVector3 vertex1(vert[index1].x, vert[index1].y, vert[index1].z);
        btVector3 vertex2(vert[index2].x, vert[index2].y, vert[index2].z);

		trimesh->addTriangle(vertex0,vertex1,vertex2);
	}

    delete [] vertices;
    delete [] indices;
    
    btCollisionShape* colShape = new btConvexTriangleMeshShape(trimesh);
    const btVector3& scale = colShape->getLocalScaling();
    colShape->calculateLocalInertia(mass,localInertia);
    collisionShapes.push_back(colShape);
    
    btTransform trans;
    trans.setIdentity();
    btDefaultMotionState* motionState = new btDefaultMotionState(trans);
    btRigidBody::btRigidBodyConstructionInfo rbInfo(mass,motionState,colShape,localInertia);
    btRigidBody* body = new btRigidBody(rbInfo);
    dynamicsWorld->addRigidBody(body);
    
    // link RigidBody and SceneNode
    Ogre::SceneNode* node = ent->getParentSceneNode();
    body->setUserPointer((void*)node);
    
    return true;
}
Example #6
0
bool VertexPair::intersection(const VertexPair& other, FloatPoint& point) const
{
    // See: http://paulbourke.net/geometry/pointlineplane/, "Intersection point of two lines in 2 dimensions"

    const FloatSize& thisDelta = vertex2() - vertex1();
    const FloatSize& otherDelta = other.vertex2() - other.vertex1();
    float denominator = determinant(thisDelta, otherDelta);
    if (!denominator)
        return false;

    // The two line segments: "this" vertex1,vertex2 and "other" vertex1,vertex2, have been defined
    // in parametric form. Each point on the line segment is: vertex1 + u * (vertex2 - vertex1),
    // when 0 <= u <= 1. We're computing the values of u for each line at their intersection point.

    const FloatSize& vertex1Delta = vertex1() - other.vertex1();
    float uThisLine = determinant(otherDelta, vertex1Delta) / denominator;
    float uOtherLine = determinant(thisDelta, vertex1Delta) / denominator;

    if (uThisLine < 0 || uOtherLine < 0 || uThisLine > 1 || uOtherLine > 1)
        return false;

    point = vertex1() + uThisLine * thisDelta;
    return true;
}
Example #7
0
void BulletObject::CreateFromEntity()
{
	bool wasPolygonGroup = false;

	RenderObject * renderObject = ((RenderComponent*)entity->GetComponent(Component::RENDER_COMPONENT))->GetRenderObject();
	uint32 batchesCount = renderObject->GetRenderBatchCount();
	for(uint32 batchIndex = 0; batchIndex < batchesCount; ++batchIndex)
	{
		RenderBatch * batch = renderObject->GetRenderBatch(batchIndex);
		PolygonGroup * pg = batch->GetPolygonGroup();
		if(pg)
		{
			if(!wasPolygonGroup)
			{
				collisionObject = new btCollisionObject();
				trimesh = new btTriangleMesh();
				createdWith = entity->GetWorldTransform();
				wasPolygonGroup = true;
			}

			for(int32 i = 0; i < pg->indexCount / 3; i++)
			{
				uint16 index0 = pg->indexArray[i*3];
				uint16 index1 = pg->indexArray[i*3+1];
				uint16 index2 = pg->indexArray[i*3+2];
				Vector3 v;
				pg->GetCoord(index0, v);
				v = v * createdWith;
				btVector3 vertex0(v.x, v.y, v.z);
				pg->GetCoord(index1, v);
				v = v * createdWith;
				btVector3 vertex1(v.x, v.y, v.z);
				pg->GetCoord(index2, v);
				v = v * createdWith;
				btVector3 vertex2(v.x, v.y, v.z);

				trimesh->addTriangle(vertex0,vertex1,vertex2, false);
			}
		}
	}

	if(wasPolygonGroup)
	{
		shape = new btBvhTriangleMeshShape(trimesh, true, true);    
		collisionObject->setCollisionShape(shape);
		collWorld->addCollisionObject(collisionObject);
	}
}
Example #8
0
void BulletObject::CreateCollisionObject()
{
	collisionObject = new btCollisionObject();
	
	trimesh = new btTriangleMesh();
	
	//const Vector<StaticMesh*> & meshes = meshNode->GetMeshes();
	//const Vector<int32> & indexes = meshNode->GetPolygonGroupIndexes();
	const Vector<PolygonGroupWithMaterial*> & polygroups = meshNode->GetPolygonGroups();
    
    
	uint32 meshesSize = (uint32)polygroups.size();

	createdWith = meshNode->GetWorldTransform();
	if (meshesSize > 0)
	{
		for (uint32 k = 0; k < meshesSize; ++k)
		{
			PolygonGroup * pg = polygroups[k]->GetPolygonGroup();    
			
			int i;
			for (i = 0; i < pg->indexCount / 3; i++)
			{
				uint16 index0 = pg->indexArray[i*3];
				uint16 index1 = pg->indexArray[i*3+1];
				uint16 index2 = pg->indexArray[i*3+2];
				Vector3 v;
				pg->GetCoord(index0, v);
				v = v * createdWith;
				btVector3 vertex0(v.x, v.y, v.z);
				pg->GetCoord(index1, v);
				v = v * createdWith;
				btVector3 vertex1(v.x, v.y, v.z);
				pg->GetCoord(index2, v);
				v = v * createdWith;
				btVector3 vertex2(v.x, v.y, v.z);
				
				trimesh->addTriangle(vertex0,vertex1,vertex2, false);
			}
		}
		shape = new btBvhTriangleMeshShape(trimesh, true, true);    

        collisionObject->setCollisionShape(shape);
        collWorld->addCollisionObject(collisionObject);
	}
	
}
btCollisionShape *Enco3D::Physics::ConvexMeshCollisionShape::toBulletPhysicsCollisionShape()
{
	btTriangleMesh *triangleMesh = new btTriangleMesh;
	for (unsigned int i = 0; i < m_mesh->getIndexCount(); i += 3)
	{
		unsigned int index0 = m_mesh->getIndices()[i + 0];
		unsigned int index1 = m_mesh->getIndices()[i + 1];
		unsigned int index2 = m_mesh->getIndices()[i + 2];

		btVector3 vertex0(m_mesh->getVertices()[index0].x, m_mesh->getVertices()[index0].y, m_mesh->getVertices()[index0].z);
		btVector3 vertex1(m_mesh->getVertices()[index1].x, m_mesh->getVertices()[index1].y, m_mesh->getVertices()[index1].z);
		btVector3 vertex2(m_mesh->getVertices()[index2].x, m_mesh->getVertices()[index2].y, m_mesh->getVertices()[index2].z);

		triangleMesh->addTriangle(vertex0, vertex1, vertex2);
	}

	return new btConvexTriangleMeshShape(triangleMesh, true);
}
/**
 *  init opens and parses the raw file "filename".
 * .raw files consist of lines as such:
 * f1 f2 f3 f4 f5 f6 f7 f8 f9
 *  These are all floats, where each triplet specifies one vertice of the triangle (to be read as:
 * v1: (f1, f2, f3); v2: (f4, f5, f6); v3: (f7, f8, f9)
 *  init populates class variable vertices with this information
 */
int
rawReader::init(const char* filename){
	std::string str = "" ; 
	
	plint = true;

	// open .raw file
	std::cout << "Reading .raw file " << filename << std::endl;
    std::ifstream in ; 
    in.open(filename) ; 
    if (!in.is_open()) {
		std::cerr << "Unable to open file " << filename << "\n" ; 
		return 1 ;
	}

	// parse .raw file
	while(in){
		getline(in, str);

		if(str.empty()){
			// do nothing
		} // read and store vertices
		else{
			float x1,y1,z1;
			float x2,y2,z2;
			float x3,y3,z3;
			sscanf(str.c_str(), "%f %f %f %f %f %f %f %f %f", &x1, &y1, &z1, &x2, &y2, &z2, &x3, &y3, &z3);
			vec3 vertex1(x1,y1,z1);
			vec3 vertex2(x2,y2,z2);
			vec3 vertex3(x3,y3,z3);
			vertices.push_back(vertex1);
			vertices.push_back(vertex2);
			vertices.push_back(vertex3);
		} 
	}
	
	calculateNormals();

	std::cout << ".raw file read successful" << std::endl;
	return 0;
}
Example #11
0
std::shared_ptr<GenericDataArray<float> > MeshManager::generateNormals(
	std::shared_ptr<GenericDataArray<float> > vertices,
	std::shared_ptr<GenericDataArray<unsigned int> > indices)
{
	std::vector<glm::vec3> normalsVec(vertices->length());
	std::shared_ptr<GenericDataArray<float> > normals = std::make_shared<GenericDataArray<float> >(vertices->length());

	for (unsigned int i = 0; i < indices->length(); ++i) {
		unsigned int vertexIndex = indices->at(i, 0);
		glm::vec3 vertex1(vertices->at(vertexIndex, 0), vertices->at(vertexIndex, 1), vertices->at(vertexIndex, 2));

		vertexIndex = indices->at(i, 1);
		glm::vec3 vertex2(vertices->at(vertexIndex, 0), vertices->at(vertexIndex, 1), vertices->at(vertexIndex, 2));

		vertexIndex = indices->at(i, 2);
		glm::vec3 vertex3(vertices->at(vertexIndex, 0), vertices->at(vertexIndex, 1), vertices->at(vertexIndex, 2));

		glm::vec3 edge1 = vertex2 - vertex1;
		glm::vec3 edge2 = vertex3 - vertex1;

		glm::vec3 normal = glm::normalize(glm::cross(edge1, edge2));

		for (unsigned int j = 0; j < 3; ++j) {
			if (normalsVec.at(indices->at(i, j)) != glm::vec3()) {
				normalsVec.at(indices->at(i, j)) = glm::normalize(normalsVec.at(indices->at(i, j)) + normal);
			}
			else {
				normalsVec.at(indices->at(i, j)) = normal;
			}
		}
	}

	for (unsigned int i = 0; i < normalsVec.size(); ++i) {
		normals->at(i) = GenericDataArray<float>::value_type(&normalsVec[i][0]);
	}

	return normals;
}
Example #12
0
void PrimitiveMeshHelper::SolidCube(float width, float height, float depth) {
  SR_ASSERT(width > 0 && height > 0 && depth > 0);
  width = width/2;
  height = height/2;
  depth = depth/2;

  DrawCmdData<Vertex> cmd;
  cmd.draw_mode = kDrawTriangles;
  VertexList &vert_list = cmd.vertex_list;
  std::vector<unsigned short> &index_list = cmd.index_list;

  //normal
  {
    // Front Face
    int baseIndex = vert_list.size();
    vec3 normal(0, 0, +1);

    vec2 texCoord1(0, 0);	vec3 vertex1(-width, -height, depth);
    vec2 texCoord2(1, 0);	vec3 vertex2( width, -height, depth);
    vec2 texCoord3(1, 1);	vec3 vertex3( width,  height, depth);
    vec2 texCoord4(0, 1);	vec3 vertex4(-width,  height, depth);

    //add vertex
    Vertex v1;  v1.pos = vertex1; v1.texcoord = texCoord1;  v1.normal = normal;
    Vertex v2;  v2.pos = vertex2; v2.texcoord = texCoord2;  v2.normal = normal;
    Vertex v3;  v3.pos = vertex3; v3.texcoord = texCoord3;  v3.normal = normal;
    Vertex v4;  v4.pos = vertex4; v4.texcoord = texCoord4;  v4.normal = normal;

    vert_list.push_back(v1);
    vert_list.push_back(v2);
    vert_list.push_back(v3);
    vert_list.push_back(v4);

    //add index
    index_list.push_back(baseIndex + 0);
    index_list.push_back(baseIndex + 1);
    index_list.push_back(baseIndex + 2);

    index_list.push_back(baseIndex + 0);
    index_list.push_back(baseIndex + 2);
    index_list.push_back(baseIndex + 3);
  }
  {
    // Back Face
    int baseIndex = vert_list.size();
    vec3 normal(0, 0, -1);

    vec2 texCoord1(1, 0);	vec3 vertex1(-width, -height, -depth);
    vec2 texCoord2(1, 1);	vec3 vertex2(-width,  height, -depth);
    vec2 texCoord3(0, 1);	vec3 vertex3( width,  height, -depth);
    vec2 texCoord4(0, 0);	vec3 vertex4( width, -height, -depth);

    //add vertex
    Vertex v1;  v1.pos = vertex1; v1.texcoord = texCoord1;  v1.normal = normal;
    Vertex v2;  v2.pos = vertex2; v2.texcoord = texCoord2;  v2.normal = normal;
    Vertex v3;  v3.pos = vertex3; v3.texcoord = texCoord3;  v3.normal = normal;
    Vertex v4;  v4.pos = vertex4; v4.texcoord = texCoord4;  v4.normal = normal;

    vert_list.push_back(v1);
    vert_list.push_back(v2);
    vert_list.push_back(v3);
    vert_list.push_back(v4);

    //add index
    index_list.push_back(baseIndex + 0);
    index_list.push_back(baseIndex + 1);
    index_list.push_back(baseIndex + 2);

    index_list.push_back(baseIndex + 0);
    index_list.push_back(baseIndex + 2);
    index_list.push_back(baseIndex + 3);
  }

  {
    // Top Face
    int baseIndex = vert_list.size();
    vec3 normal(0, 1, 0);

    vec2 texCoord1(0, 1);	vec3 vertex1(-width, height, -depth);
    vec2 texCoord2(0, 0);	vec3 vertex2(-width, height,  depth);
    vec2 texCoord3(1, 0);	vec3 vertex3( width, height,  depth);
    vec2 texCoord4(1, 1);	vec3 vertex4( width, height, -depth);

    //add vertex
    Vertex v1;  v1.pos = vertex1; v1.texcoord = texCoord1;  v1.normal = normal;
    Vertex v2;  v2.pos = vertex2; v2.texcoord = texCoord2;  v2.normal = normal;
    Vertex v3;  v3.pos = vertex3; v3.texcoord = texCoord3;  v3.normal = normal;
    Vertex v4;  v4.pos = vertex4; v4.texcoord = texCoord4;  v4.normal = normal;

    vert_list.push_back(v1);
    vert_list.push_back(v2);
    vert_list.push_back(v3);
    vert_list.push_back(v4);

    //add index
    index_list.push_back(baseIndex + 0);
    index_list.push_back(baseIndex + 1);
    index_list.push_back(baseIndex + 2);

    index_list.push_back(baseIndex + 0);
    index_list.push_back(baseIndex + 2);
    index_list.push_back(baseIndex + 3);
  }

  {
    // Bottom Face
    int baseIndex = vert_list.size();
    vec3 normal(0, -1, 0);

    vec2 texCoord1(1, 1);	vec3 vertex1(-width, -height, -depth);
    vec2 texCoord2(0, 1);	vec3 vertex2( width, -height, -depth);
    vec2 texCoord3(0, 0);	vec3 vertex3( width, -height,  depth);
    vec2 texCoord4(1, 0);	vec3 vertex4(-width, -height,  depth);

    //add vertex
    Vertex v1;  v1.pos = vertex1; v1.texcoord = texCoord1;  v1.normal = normal;
    Vertex v2;  v2.pos = vertex2; v2.texcoord = texCoord2;  v2.normal = normal;
    Vertex v3;  v3.pos = vertex3; v3.texcoord = texCoord3;  v3.normal = normal;
    Vertex v4;  v4.pos = vertex4; v4.texcoord = texCoord4;  v4.normal = normal;

    vert_list.push_back(v1);
    vert_list.push_back(v2);
    vert_list.push_back(v3);
    vert_list.push_back(v4);

    //add index
    index_list.push_back(baseIndex + 0);
    index_list.push_back(baseIndex + 1);
    index_list.push_back(baseIndex + 2);

    index_list.push_back(baseIndex + 0);
    index_list.push_back(baseIndex + 2);
    index_list.push_back(baseIndex + 3);
  }

  {
    // Right face
    int baseIndex = vert_list.size();
    vec3 normal(1, 0, 0);

    vec2 texCoord1(1, 0);	vec3 vertex1(width, -height, -depth);
    vec2 texCoord2(1, 1);	vec3 vertex2(width,  height, -depth);
    vec2 texCoord3(0, 1);	vec3 vertex3(width,  height,  depth);
    vec2 texCoord4(0, 0);	vec3 vertex4(width, -height,  depth);

    //add vertex
    Vertex v1;  v1.pos = vertex1; v1.texcoord = texCoord1;  v1.normal = normal;
    Vertex v2;  v2.pos = vertex2; v2.texcoord = texCoord2;  v2.normal = normal;
    Vertex v3;  v3.pos = vertex3; v3.texcoord = texCoord3;  v3.normal = normal;
    Vertex v4;  v4.pos = vertex4; v4.texcoord = texCoord4;  v4.normal = normal;

    vert_list.push_back(v1);
    vert_list.push_back(v2);
    vert_list.push_back(v3);
    vert_list.push_back(v4);

    //add index
    index_list.push_back(baseIndex + 0);
    index_list.push_back(baseIndex + 1);
    index_list.push_back(baseIndex + 2);

    index_list.push_back(baseIndex + 0);
    index_list.push_back(baseIndex + 2);
    index_list.push_back(baseIndex + 3);
  }

  {
    // Left Face
    int baseIndex = vert_list.size();
    vec3 normal(0, -1, 0);

    vec2 texCoord1(0, 0);	vec3 vertex1(-width, -height, -depth);
    vec2 texCoord2(1, 0);	vec3 vertex2(-width, -height,  depth);
    vec2 texCoord3(1, 1);	vec3 vertex3(-width,  height,  depth);
    vec2 texCoord4(0, 1);	vec3 vertex4(-width,  height, -depth);

    //add vertex
    Vertex v1;  v1.pos = vertex1; v1.texcoord = texCoord1;  v1.normal = normal;
    Vertex v2;  v2.pos = vertex2; v2.texcoord = texCoord2;  v2.normal = normal;
    Vertex v3;  v3.pos = vertex3; v3.texcoord = texCoord3;  v3.normal = normal;
    Vertex v4;  v4.pos = vertex4; v4.texcoord = texCoord4;  v4.normal = normal;

    vert_list.push_back(v1);
    vert_list.push_back(v2);
    vert_list.push_back(v3);
    vert_list.push_back(v4);

    //add index
    index_list.push_back(baseIndex + 0);
    index_list.push_back(baseIndex + 1);
    index_list.push_back(baseIndex + 2);

    index_list.push_back(baseIndex + 0);
    index_list.push_back(baseIndex + 2);
    index_list.push_back(baseIndex + 3);
  }
  this->cmd_list_->push_back(cmd);
}
Example #13
0
void TriangleWindow::generateTerrain()
{
    float scale = .2f;

    GLfloat y1;
    GLfloat y2;
    GLfloat y3;
    GLfloat y4;

    if (QFile::exists(":/heightmap-2.png")) {
        if(!m_image.load(":/heightmap-2.png"))
        {
            std::cout << "image non chargé ";
            exit(0);
        }
    }
    else
    {
        std::cout << "image not found ";
    }

    for(int x = 0; x < m_image.width() - 1; x++)
    {
        for(int z = 0; z < m_image.height() - 1; z++)
        {
            unsigned char* line = m_image.scanLine(z);
            unsigned char* line2 = m_image.scanLine(z+1);
            y1 = (((GLfloat)line[x*4])/255)*20;
            y2 = (((GLfloat)line[(x*4)+4])/255)*20;
            y3 = (((GLfloat)line2[(x*4)])/255)*20;
            y4 = (((GLfloat)line2[(x*4)+4])/255)*20;

            _texture.push_back(x/(m_image.width()*1.0)); _texture.push_back(z/(m_image.height()*1.0));
            _texture.push_back((x+1)/(m_image.width()*1.0)); _texture.push_back(z/(m_image.height()*1.0));
            _texture.push_back(x/(m_image.width()*1.0)); _texture.push_back((z+1)/(m_image.height()*1.0));

            _texture.push_back((x+1)/(m_image.width()*1.0)); _texture.push_back(z/(m_image.height()*1.0));
            _texture.push_back(x/(m_image.width()*1.0)); _texture.push_back((z+1)/(m_image.height()*1.0));
            _texture.push_back((x+1)/(m_image.width()*1.0)); _texture.push_back((z+1)/(m_image.height()*1.0));

            QVector3D vertex1(x*scale, y1, z*scale);
            _map.push_back(vertex1);
            _color.push_back(displayColor(y1));

            QVector3D vertex2((x+1)*scale, y2, z*scale);
            _map.push_back(vertex2);
            _color.push_back(displayColor(y2));

            QVector3D vertex3(x*scale, y3, (z+1)*scale);
            _map.push_back(vertex3);
            _color.push_back(displayColor(y3));

            QVector3D normal = QVector3D::normal(vertex1, vertex2, vertex3);
            _normal.push_back(normal);

            normal = QVector3D::normal(vertex2, vertex3, vertex1);
            _normal.push_back(normal);

            normal = QVector3D::normal(vertex3, vertex1, vertex2);
            _normal.push_back(normal);

            _map.push_back(vertex2);
            _color.push_back(displayColor(y2));

            QVector3D vertex4((x+1)*scale, y4, (z+1)*scale);
            _map.push_back(vertex4);
            _color.push_back(displayColor(y4));

            _map.push_back(vertex3);
            _color.push_back(displayColor(y3));

            normal = QVector3D::normal(vertex2, vertex4, vertex3);
            _normal.push_back(normal);

            normal = QVector3D::normal(vertex4, vertex3, vertex2);
            _normal.push_back(normal);

            normal = QVector3D::normal(vertex3, vertex2, vertex4);
            _normal.push_back(normal);
        }
    }
}
Example #14
0
			virtual void ConvexDecompResult(ConvexDecomposition::ConvexResult &result)
			{

				btTriangleMesh* trimesh = new btTriangleMesh();
				m_convexDemo->m_trimeshes.push_back(trimesh);

				btVector3 localScaling(6.f,6.f,6.f);

				//export data to .obj
				printf("ConvexResult. ");
				if (mOutputFile)
				{
					fprintf(mOutputFile,"## Hull Piece %d with %d vertices and %d triangles.\r\n", mHullCount, result.mHullVcount, result.mHullTcount );

					fprintf(mOutputFile,"usemtl Material%i\r\n",mBaseCount);
					fprintf(mOutputFile,"o Object%i\r\n",mBaseCount);

					for (unsigned int i=0; i<result.mHullVcount; i++)
					{
						const float *p = &result.mHullVertices[i*3];
						fprintf(mOutputFile,"v %0.9f %0.9f %0.9f\r\n", p[0], p[1], p[2] );
					}

					//calc centroid, to shift vertices around center of mass
					centroid.setValue(0,0,0);

					btAlignedObjectArray<btVector3> vertices;
					if ( 1 )
					{
						//const unsigned int *src = result.mHullIndices;
						for (unsigned int i=0; i<result.mHullVcount; i++)
						{
							btVector3 vertex(result.mHullVertices[i*3],result.mHullVertices[i*3+1],result.mHullVertices[i*3+2]);
							vertex *= localScaling;
							centroid += vertex;

						}
					}

					centroid *= 1.f/(float(result.mHullVcount) );

					if ( 1 )
					{
						//const unsigned int *src = result.mHullIndices;
						for (unsigned int i=0; i<result.mHullVcount; i++)
						{
							btVector3 vertex(result.mHullVertices[i*3],result.mHullVertices[i*3+1],result.mHullVertices[i*3+2]);
							vertex *= localScaling;
							vertex -= centroid ;
							vertices.push_back(vertex);
						}
					}



					if ( 1 )
					{
						const unsigned int *src = result.mHullIndices;
						for (unsigned int i=0; i<result.mHullTcount; i++)
						{
							unsigned int index0 = *src++;
							unsigned int index1 = *src++;
							unsigned int index2 = *src++;


							btVector3 vertex0(result.mHullVertices[index0*3], result.mHullVertices[index0*3+1],result.mHullVertices[index0*3+2]);
							btVector3 vertex1(result.mHullVertices[index1*3], result.mHullVertices[index1*3+1],result.mHullVertices[index1*3+2]);
							btVector3 vertex2(result.mHullVertices[index2*3], result.mHullVertices[index2*3+1],result.mHullVertices[index2*3+2]);
							vertex0 *= localScaling;
							vertex1 *= localScaling;
							vertex2 *= localScaling;

							vertex0 -= centroid;
							vertex1 -= centroid;
							vertex2 -= centroid;


							trimesh->addTriangle(vertex0,vertex1,vertex2);

							index0+=mBaseCount;
							index1+=mBaseCount;
							index2+=mBaseCount;

							fprintf(mOutputFile,"f %d %d %d\r\n", index0+1, index1+1, index2+1 );
						}
					}

				//	float mass = 1.f;


//this is a tools issue: due to collision margin, convex objects overlap, compensate for it here:
//#define SHRINK_OBJECT_INWARDS 1
#ifdef SHRINK_OBJECT_INWARDS

					float collisionMargin = 0.01f;

					btAlignedObjectArray<btVector3> planeEquations;
					btGeometryUtil::getPlaneEquationsFromVertices(vertices,planeEquations);

					btAlignedObjectArray<btVector3> shiftedPlaneEquations;
					for (int p=0;p<planeEquations.size();p++)
					{
						btVector3 plane = planeEquations[p];
						plane[3] += collisionMargin;
						shiftedPlaneEquations.push_back(plane);
					}
					btAlignedObjectArray<btVector3> shiftedVertices;
					btGeometryUtil::getVerticesFromPlaneEquations(shiftedPlaneEquations,shiftedVertices);


					btConvexHullShape* convexShape = new btConvexHullShape(&(shiftedVertices[0].getX()),shiftedVertices.size());

#else //SHRINK_OBJECT_INWARDS

					btConvexHullShape* convexShape = new btConvexHullShape(&(vertices[0].getX()),vertices.size());
#endif
					if (sEnableSAT)
						convexShape->initializePolyhedralFeatures();
					convexShape->setMargin(0.01f);
					m_convexShapes.push_back(convexShape);
					m_convexCentroids.push_back(centroid);
					m_convexDemo->m_collisionShapes.push_back(convexShape);
					mBaseCount+=result.mHullVcount; // advance the 'base index' counter.


				}
			}
Example #15
0
void CTexturedLineRData::Update(const SOverlayTexturedLine& line)
{
	if (m_VB)
	{
		g_VBMan.Release(m_VB);
		m_VB = NULL;
	}
	if (m_VBIndices)
	{
		g_VBMan.Release(m_VBIndices);
		m_VBIndices = NULL;
	}

	if (!line.m_SimContext)
	{
		debug_warn(L"[TexturedLineRData] No SimContext set for textured overlay line, cannot render (no terrain data)");
		return;
	}

	const CTerrain& terrain = line.m_SimContext->GetTerrain();
	CmpPtr<ICmpWaterManager> cmpWaterManager(*line.m_SimContext, SYSTEM_ENTITY);

	float v = 0.f;
	std::vector<SVertex> vertices;
	std::vector<u16> indices;

	size_t n = line.m_Coords.size() / 2; // number of line points
	bool closed = line.m_Closed;

	ENSURE(n >= 2); // minimum needed to avoid errors (also minimum value to make sense, can't draw a line between 1 point)

	// In each iteration, p1 is the position of vertex i, p0 is i-1, p2 is i+1.
	// To avoid slightly expensive terrain computations we cycle these around and
	// recompute p2 at the end of each iteration.

	CVector3D p0;
	CVector3D p1(line.m_Coords[0], 0, line.m_Coords[1]);
	CVector3D p2(line.m_Coords[(1 % n)*2], 0, line.m_Coords[(1 % n)*2+1]);

	if (closed)
		// grab the ending point so as to close the loop
		p0 = CVector3D(line.m_Coords[(n-1)*2], 0, line.m_Coords[(n-1)*2+1]);
	else
		// we don't want to loop around and use the direction towards the other end of the line, so create an artificial p0 that 
		// extends the p2 -> p1 direction, and use that point instead
		p0 = p1 + (p1 - p2);

	bool p1floating = false;
	bool p2floating = false;

	// Compute terrain heights, clamped to the water height (and remember whether
	// each point was floating on water, for normal computation later)

	// TODO: if we ever support more than one water level per map, recompute this per point
	float w = cmpWaterManager->GetExactWaterLevel(p0.X, p0.Z);

	p0.Y = terrain.GetExactGroundLevel(p0.X, p0.Z);
	if (p0.Y < w)
		p0.Y = w;

	p1.Y = terrain.GetExactGroundLevel(p1.X, p1.Z);
	if (p1.Y < w)
	{
		p1.Y = w;
		p1floating = true;
	}

	p2.Y = terrain.GetExactGroundLevel(p2.X, p2.Z);
	if (p2.Y < w)
	{
		p2.Y = w;
		p2floating = true;
	}

	for (size_t i = 0; i < n; ++i)
	{
		// For vertex i, compute bisector of lines (i-1)..(i) and (i)..(i+1)
		// perpendicular to terrain normal

		// Normal is vertical if on water, else computed from terrain
		CVector3D norm;
		if (p1floating)
			norm = CVector3D(0, 1, 0);
		else
			norm = terrain.CalcExactNormal(p1.X, p1.Z);

		CVector3D b = ((p1 - p0).Normalized() + (p2 - p1).Normalized()).Cross(norm);

		// Adjust bisector length to match the line thickness, along the line's width
		float l = b.Dot((p2 - p1).Normalized().Cross(norm));
		if (fabs(l) > 0.000001f) // avoid unlikely divide-by-zero
			b *= line.m_Thickness / l;

		// Push vertices and indices for each quad in GL_TRIANGLES order. The two triangles of each quad are indexed using
		// the winding orders (BR, BL, TR) and (TR, BL, TR) (where BR is bottom-right of this iteration's quad, TR top-right etc).
		SVertex vertex1(p1 + b + norm*OverlayRenderer::OVERLAY_VOFFSET, 0.f, v);
		SVertex vertex2(p1 - b + norm*OverlayRenderer::OVERLAY_VOFFSET, 1.f, v);
		vertices.push_back(vertex1);
		vertices.push_back(vertex2);

		u16 index1 = vertices.size() - 2; // index of vertex1 in this iteration (TR of this quad)
		u16 index2 = vertices.size() - 1; // index of the vertex2 in this iteration (TL of this quad)

		if (i == 0)
		{
			// initial two vertices to continue building triangles from (n must be >= 2 for this to work)
			indices.push_back(index1);
			indices.push_back(index2);
		}
		else 
		{
			u16 index1Prev = vertices.size() - 4; // index of the vertex1 in the previous iteration (BR of this quad)
			u16 index2Prev = vertices.size() - 3; // index of the vertex2 in the previous iteration (BL of this quad)
			ENSURE(index1Prev < vertices.size());
			ENSURE(index2Prev < vertices.size());
			// Add two corner points from last iteration and join with one of our own corners to create triangle 1
			// (don't need to do this if i == 1 because i == 0 are the first two ones, they don't need to be copied)
			if (i > 1)
			{
				indices.push_back(index1Prev);
				indices.push_back(index2Prev);
			}
			indices.push_back(index1); // complete triangle 1

			// create triangle 2, specifying the adjacent side's vertices in the opposite order from triangle 1
			indices.push_back(index1);
			indices.push_back(index2Prev);
			indices.push_back(index2);
		}

		// alternate V coordinate for debugging
		v = 1 - v;

		// cycle the p's and compute the new p2
		p0 = p1;
		p1 = p2;
		p1floating = p2floating;

		// if in closed mode, wrap around the coordinate array for p2 -- otherwise, extend linearly
		if (!closed && i == n-2)
			// next iteration is the last point of the line, so create an artificial p2 that extends the p0 -> p1 direction
			p2 = p1 + (p1 - p0);
		else
			p2 = CVector3D(line.m_Coords[((i+2) % n)*2], 0, line.m_Coords[((i+2) % n)*2+1]);

		p2.Y = terrain.GetExactGroundLevel(p2.X, p2.Z);
		if (p2.Y < w)
		{
			p2.Y = w;
			p2floating = true;
		}
		else
			p2floating = false;
	}

	if (closed)
	{
		// close the path
		indices.push_back(vertices.size()-2);
		indices.push_back(vertices.size()-1);
		indices.push_back(0);

		indices.push_back(0);
		indices.push_back(vertices.size()-1);
		indices.push_back(1);
	}
	else
	{
		// Create start and end caps. On either end, this is done by taking the centroid between the last and second-to-last pair of
		// vertices that was generated along the path (i.e. the vertex1's and vertex2's from above), taking a directional vector 
		// between them, and drawing the line cap in the plane given by the two butt-end corner points plus said vector.
		std::vector<u16> capIndices;
		std::vector<SVertex> capVertices;

		// create end cap
		CreateLineCap(
			line,
			// the order of these vertices is important here, swapping them produces caps at the wrong side
			vertices[vertices.size()-2].m_Position, // top-right vertex of last quad
			vertices[vertices.size()-1].m_Position, // top-left vertex of last quad
			// directional vector between centroids of last vertex pair and second-to-last vertex pair
			(Centroid(vertices[vertices.size()-2], vertices[vertices.size()-1]) - Centroid(vertices[vertices.size()-4], vertices[vertices.size()-3])).Normalized(),
			line.m_EndCapType,
			capVertices,
			capIndices
		);

		for (unsigned i = 0; i < capIndices.size(); i++)
			capIndices[i] += vertices.size();

		vertices.insert(vertices.end(), capVertices.begin(), capVertices.end());
		indices.insert(indices.end(), capIndices.begin(), capIndices.end());

		capIndices.clear();
		capVertices.clear();

		// create start cap
		CreateLineCap(
			line,
			// the order of these vertices is important here, swapping them produces caps at the wrong side
			vertices[1].m_Position,
			vertices[0].m_Position,
			// directional vector between centroids of first vertex pair and second vertex pair
			(Centroid(vertices[1], vertices[0]) - Centroid(vertices[3], vertices[2])).Normalized(),
			line.m_StartCapType,
			capVertices,
			capIndices
		);

		for (unsigned i = 0; i < capIndices.size(); i++)
			capIndices[i] += vertices.size();

		vertices.insert(vertices.end(), capVertices.begin(), capVertices.end());
		indices.insert(indices.end(), capIndices.begin(), capIndices.end());
	}

	ENSURE(indices.size() % 3 == 0); // GL_TRIANGLES indices, so must be multiple of 3

	m_VB = g_VBMan.Allocate(sizeof(SVertex), vertices.size(), GL_STATIC_DRAW, GL_ARRAY_BUFFER);
	if (m_VB) // allocation might fail (e.g. due to too many vertices)
	{
		m_VB->m_Owner->UpdateChunkVertices(m_VB, &vertices[0]); // copy data into VBO

		for (size_t k = 0; k < indices.size(); ++k)
			indices[k] += m_VB->m_Index;

		m_VBIndices = g_VBMan.Allocate(sizeof(u16), indices.size(), GL_STATIC_DRAW, GL_ELEMENT_ARRAY_BUFFER);
		if (m_VBIndices)
			m_VBIndices->m_Owner->UpdateChunkVertices(m_VBIndices, &indices[0]);
	}

}
Example #16
0
int main(int argc,char** argv)
{

	int i;
	for (i=0;i<numObjects;i++)
	{
		if (i>0)
		{
			shapePtr[i] = prebuildShapePtr[1];
			shapeIndex[i] = 1;//sphere
		}
		else
		{
			shapeIndex[i] = 0;
			shapePtr[i] = prebuildShapePtr[0];
		}
	}
	
	ConvexDecomposition::WavefrontObj wo;
	char* filename = "file.obj";
	tcount = wo.loadObj(filename);

	class MyConvexDecomposition : public ConvexDecomposition::ConvexDecompInterface
	{
		public:

		MyConvexDecomposition (FILE* outputFile)
			:mBaseCount(0),
			mHullCount(0),
			mOutputFile(outputFile)

		{
		}
		
			virtual void ConvexDecompResult(ConvexDecomposition::ConvexResult &result)
			{

				TriangleMesh* trimesh = new TriangleMesh();

				SimdVector3 localScaling(6.f,6.f,6.f);

				//export data to .obj
				printf("ConvexResult\n");
				if (mOutputFile)
				{
					fprintf(mOutputFile,"## Hull Piece %d with %d vertices and %d triangles.\r\n", mHullCount, result.mHullVcount, result.mHullTcount );

					fprintf(mOutputFile,"usemtl Material%i\r\n",mBaseCount);
					fprintf(mOutputFile,"o Object%i\r\n",mBaseCount);

					for (unsigned int i=0; i<result.mHullVcount; i++)
					{
						const float *p = &result.mHullVertices[i*3];
						fprintf(mOutputFile,"v %0.9f %0.9f %0.9f\r\n", p[0], p[1], p[2] );
					}

					//calc centroid, to shift vertices around center of mass
					centroids[numObjects] = SimdVector3(0,0,0);
					if ( 1 )
					{
						const unsigned int *src = result.mHullIndices;
						for (unsigned int i=0; i<result.mHullTcount; i++)
						{
							unsigned int index0 = *src++;
							unsigned int index1 = *src++;
							unsigned int index2 = *src++;
							SimdVector3 vertex0(result.mHullVertices[index0*3], result.mHullVertices[index0*3+1],result.mHullVertices[index0*3+2]);
							SimdVector3 vertex1(result.mHullVertices[index1*3], result.mHullVertices[index1*3+1],result.mHullVertices[index1*3+2]);
							SimdVector3 vertex2(result.mHullVertices[index2*3], result.mHullVertices[index2*3+1],result.mHullVertices[index2*3+2]);
							vertex0 *= localScaling;
							vertex1 *= localScaling;
							vertex2 *= localScaling;
							centroids[numObjects] += vertex0;
							centroids[numObjects]+= vertex1;
							centroids[numObjects]+= vertex2;
							
						}
					}

					centroids[numObjects] *= 1.f/(float(result.mHullTcount) * 3);

					if ( 1 )
					{
						const unsigned int *src = result.mHullIndices;
						for (unsigned int i=0; i<result.mHullTcount; i++)
						{
							unsigned int index0 = *src++;
							unsigned int index1 = *src++;
							unsigned int index2 = *src++;


							SimdVector3 vertex0(result.mHullVertices[index0*3], result.mHullVertices[index0*3+1],result.mHullVertices[index0*3+2]);
							SimdVector3 vertex1(result.mHullVertices[index1*3], result.mHullVertices[index1*3+1],result.mHullVertices[index1*3+2]);
							SimdVector3 vertex2(result.mHullVertices[index2*3], result.mHullVertices[index2*3+1],result.mHullVertices[index2*3+2]);
							vertex0 *= localScaling;
							vertex1 *= localScaling;
							vertex2 *= localScaling;
							
							vertex0 -= centroids[numObjects];
							vertex1 -= centroids[numObjects];
							vertex2 -= centroids[numObjects];

							trimesh->AddTriangle(vertex0,vertex1,vertex2);

							index0+=mBaseCount;
							index1+=mBaseCount;
							index2+=mBaseCount;
							
							fprintf(mOutputFile,"f %d %d %d\r\n", index0+1, index1+1, index2+1 );
						}
					}

					shapeIndex[numObjects] = numObjects;
					shapePtr[numObjects++] = new ConvexTriangleMeshShape(trimesh);
					
					mBaseCount+=result.mHullVcount; // advance the 'base index' counter.


				}
			}

			int   	mBaseCount;
  			int		mHullCount;
			FILE*	mOutputFile;

	};

	if (tcount)
	{
		numObjects = 1; //always have the ground object first
		
		TriangleMesh* trimesh = new TriangleMesh();

		SimdVector3 localScaling(6.f,6.f,6.f);
		
		for (int i=0;i<wo.mTriCount;i++)
		{
			int index0 = wo.mIndices[i*3];
			int index1 = wo.mIndices[i*3+1];
			int index2 = wo.mIndices[i*3+2];

			SimdVector3 vertex0(wo.mVertices[index0*3], wo.mVertices[index0*3+1],wo.mVertices[index0*3+2]);
			SimdVector3 vertex1(wo.mVertices[index1*3], wo.mVertices[index1*3+1],wo.mVertices[index1*3+2]);
			SimdVector3 vertex2(wo.mVertices[index2*3], wo.mVertices[index2*3+1],wo.mVertices[index2*3+2]);
			
			vertex0 *= localScaling;
			vertex1 *= localScaling;
			vertex2 *= localScaling;

			trimesh->AddTriangle(vertex0,vertex1,vertex2);
		}

		shapePtr[numObjects++] = new ConvexTriangleMeshShape(trimesh);
	}
			

	if (tcount)
	{

		char outputFileName[512];
  		strcpy(outputFileName,filename);
  		char *dot = strstr(outputFileName,".");
  		if ( dot ) 
			*dot = 0;
		strcat(outputFileName,"_convex.obj");
  		FILE* outputFile = fopen(outputFileName,"wb");
				
		unsigned int depth = 7;
		float cpercent     = 5;
		float ppercent     = 15;
		unsigned int maxv  = 16;
		float skinWidth    = 0.01;

		printf("WavefrontObj num triangles read %i",tcount);
		ConvexDecomposition::DecompDesc desc;
		desc.mVcount       =	wo.mVertexCount;
		desc.mVertices     = wo.mVertices;
		desc.mTcount       = wo.mTriCount;
		desc.mIndices      = (unsigned int *)wo.mIndices;
		desc.mDepth        = depth;
		desc.mCpercent     = cpercent;
		desc.mPpercent     = ppercent;
		desc.mMaxVertices  = maxv;
		desc.mSkinWidth    = skinWidth;

		MyConvexDecomposition	convexDecomposition(outputFile);
		desc.mCallback = &convexDecomposition;
		
		

		//convexDecomposition.performConvexDecomposition(desc);

		ConvexBuilder cb(desc.mCallback);
		int ret = cb.process(desc);
		
		if (outputFile)
			fclose(outputFile);


	}

	CollisionDispatcher* dispatcher = new	CollisionDispatcher();


	SimdVector3 worldAabbMin(-10000,-10000,-10000);
	SimdVector3 worldAabbMax(10000,10000,10000);

	OverlappingPairCache* broadphase = new AxisSweep3(worldAabbMin,worldAabbMax);
	//OverlappingPairCache* broadphase = new SimpleBroadphase();

	physicsEnvironmentPtr = new CcdPhysicsEnvironment(dispatcher,broadphase);
	physicsEnvironmentPtr->setDeactivationTime(2.f);

	physicsEnvironmentPtr->setGravity(0,-10,0);
	PHY_ShapeProps shapeProps;

	shapeProps.m_do_anisotropic = false;
	shapeProps.m_do_fh = false;
	shapeProps.m_do_rot_fh = false;
	shapeProps.m_friction_scaling[0] = 1.;
	shapeProps.m_friction_scaling[1] = 1.;
	shapeProps.m_friction_scaling[2] = 1.;

	shapeProps.m_inertia = 1.f;
	shapeProps.m_lin_drag = 0.2f;
	shapeProps.m_ang_drag = 0.1f;
	shapeProps.m_mass = 10.0f;

	PHY_MaterialProps materialProps;
	materialProps.m_friction = 10.5f;
	materialProps.m_restitution = 0.0f;

	CcdConstructionInfo ccdObjectCi;
	ccdObjectCi.m_friction = 0.5f;

	ccdObjectCi.m_linearDamping = shapeProps.m_lin_drag;
	ccdObjectCi.m_angularDamping = shapeProps.m_ang_drag;

	SimdTransform tr;
	tr.setIdentity();



	for (i=0;i<numObjects;i++)
	{
		shapeProps.m_shape = shapePtr[shapeIndex[i]];
		shapeProps.m_shape->SetMargin(0.05f);



		bool isDyna = i>0;
		//if (i==1)
		//	isDyna=false;

		if (0)//i==1)
		{
			SimdQuaternion orn(0,0,0.1*SIMD_HALF_PI);
			ms[i].setWorldOrientation(orn.x(),orn.y(),orn.z(),orn[3]);
		}


		if (i>0)
		{

			switch (i)
			{
			case 1:
				{
					ms[i].setWorldPosition(0,10,0);
					//for testing, rotate the ground cube so the stack has to recover a bit

					break;
				}
			case 2:
				{
					ms[i].setWorldPosition(0,8,2);
					break;
				}
			default:
				ms[i].setWorldPosition(0,i*CUBE_HALF_EXTENTS*2 - CUBE_HALF_EXTENTS,0);
			}

			float quatIma0,quatIma1,quatIma2,quatReal;
			SimdQuaternion quat;
			SimdVector3 axis(0,0,1);
			SimdScalar angle=0.5f;

			quat.setRotation(axis,angle);

			ms[i].setWorldOrientation(quat.getX(),quat.getY(),quat.getZ(),quat[3]);



		} else
		{
			ms[i].setWorldPosition(0,-10+EXTRA_HEIGHT,0);

		}

		ccdObjectCi.m_MotionState = &ms[i];
		ccdObjectCi.m_gravity = SimdVector3(0,0,0);
		ccdObjectCi.m_localInertiaTensor =SimdVector3(0,0,0);
		if (!isDyna)
		{
			shapeProps.m_mass = 0.f;
			ccdObjectCi.m_mass = shapeProps.m_mass;
			ccdObjectCi.m_collisionFlags = CollisionObject::isStatic;
		}
		else
		{
			shapeProps.m_mass = 1.f;
			ccdObjectCi.m_mass = shapeProps.m_mass;
			ccdObjectCi.m_collisionFlags = 0;
		}


		SimdVector3 localInertia;
		if (shapePtr[shapeIndex[i]]->GetShapeType() == EMPTY_SHAPE_PROXYTYPE)
		{
			//take inertia from first shape
			shapePtr[1]->CalculateLocalInertia(shapeProps.m_mass,localInertia);
		} else
		{
			shapePtr[shapeIndex[i]]->CalculateLocalInertia(shapeProps.m_mass,localInertia);
		}
		ccdObjectCi.m_localInertiaTensor = localInertia;

		ccdObjectCi.m_collisionShape = shapePtr[shapeIndex[i]];


		physObjects[i]= new CcdPhysicsController( ccdObjectCi);

		// Only do CCD if  motion in one timestep (1.f/60.f) exceeds CUBE_HALF_EXTENTS
		physObjects[i]->GetRigidBody()->m_ccdSquareMotionTreshold = CUBE_HALF_EXTENTS;
		
		//Experimental: better estimation of CCD Time of Impact:
		//physObjects[i]->GetRigidBody()->m_ccdSweptShereRadius = 0.5*CUBE_HALF_EXTENTS;

		physicsEnvironmentPtr->addCcdPhysicsController( physObjects[i]);

		if (i==1)
		{
			//physObjects[i]->SetAngularVelocity(0,0,-2,true);
		}

		physicsEnvironmentPtr->setDebugDrawer(&debugDrawer);

	}


	//create a constraint
	if (createConstraint)
	{
		//physObjects[i]->SetAngularVelocity(0,0,-2,true);
		int constraintId;

		float pivotX=CUBE_HALF_EXTENTS,
			pivotY=-CUBE_HALF_EXTENTS,
			pivotZ=CUBE_HALF_EXTENTS;

		float axisX=1,axisY=0,axisZ=0;



		HingeConstraint* hinge = 0;

		SimdVector3 pivotInA(CUBE_HALF_EXTENTS,-CUBE_HALF_EXTENTS,CUBE_HALF_EXTENTS);
		SimdVector3 pivotInB(-CUBE_HALF_EXTENTS,-CUBE_HALF_EXTENTS,CUBE_HALF_EXTENTS);
		SimdVector3 axisInA(0,1,0);
		SimdVector3 axisInB(0,-1,0);

		RigidBody* rb0 = physObjects[1]->GetRigidBody();
		RigidBody* rb1 = physObjects[2]->GetRigidBody();

		hinge = new HingeConstraint(
			*rb0,
			*rb1,pivotInA,pivotInB,axisInA,axisInB);

		physicsEnvironmentPtr->m_constraints.push_back(hinge);

		hinge->SetUserConstraintId(100);
		hinge->SetUserConstraintType(PHY_LINEHINGE_CONSTRAINT);

	}




	clientResetScene();

	setCameraDistance(26.f);

	return glutmain(argc, argv,640,480,"Bullet Physics Demo. http://www.continuousphysics.com/Bullet/phpBB2/");
}
Example #17
0
void ConvexDecompositionDemo::initPhysics(const char* filename)
{

	gContactAddedCallback = &MyContactCallback;

	setupEmptyDynamicsWorld();

	getDynamicsWorld()->setDebugDrawer(&gDebugDrawer);

	setTexturing(true);
	setShadows(true);

	setCameraDistance(26.f);


#ifndef NO_OBJ_TO_BULLET

	ConvexDecomposition::WavefrontObj wo;

	tcount = 0;
    const char* prefix[]={"./","../","../../","../../../","../../../../", "ConvexDecompositionDemo/", "Demos/ConvexDecompositionDemo/",
    "../Demos/ConvexDecompositionDemo/","../../Demos/ConvexDecompositionDemo/"};
    int numPrefixes = sizeof(prefix)/sizeof(const char*);
    char relativeFileName[1024];

    for (int i=0;i<numPrefixes;i++)
    {
        sprintf(relativeFileName,"%s%s",prefix[i],filename);
        tcount = wo.loadObj(relativeFileName);
        if (tcount)
            break;
    }



	btTransform startTransform;
	startTransform.setIdentity();
	startTransform.setOrigin(btVector3(0,-4.5,0));

	btCollisionShape* boxShape = new btBoxShape(btVector3(30,2,30));
	m_collisionShapes.push_back(boxShape);
	localCreateRigidBody(0.f,startTransform,boxShape);

	class MyConvexDecomposition : public ConvexDecomposition::ConvexDecompInterface
	{
		ConvexDecompositionDemo*	m_convexDemo;

		public:

		btAlignedObjectArray<btConvexHullShape*> m_convexShapes;
		btAlignedObjectArray<btVector3> m_convexCentroids;

		MyConvexDecomposition (FILE* outputFile,ConvexDecompositionDemo* demo)
			:m_convexDemo(demo),
				mBaseCount(0),
			mHullCount(0),
			mOutputFile(outputFile)

		{
		}

			virtual void ConvexDecompResult(ConvexDecomposition::ConvexResult &result)
			{

				btTriangleMesh* trimesh = new btTriangleMesh();
				m_convexDemo->m_trimeshes.push_back(trimesh);

				btVector3 localScaling(6.f,6.f,6.f);

				//export data to .obj
				printf("ConvexResult. ");
				if (mOutputFile)
				{
					fprintf(mOutputFile,"## Hull Piece %d with %d vertices and %d triangles.\r\n", mHullCount, result.mHullVcount, result.mHullTcount );

					fprintf(mOutputFile,"usemtl Material%i\r\n",mBaseCount);
					fprintf(mOutputFile,"o Object%i\r\n",mBaseCount);

					for (unsigned int i=0; i<result.mHullVcount; i++)
					{
						const float *p = &result.mHullVertices[i*3];
						fprintf(mOutputFile,"v %0.9f %0.9f %0.9f\r\n", p[0], p[1], p[2] );
					}

					//calc centroid, to shift vertices around center of mass
					centroid.setValue(0,0,0);

					btAlignedObjectArray<btVector3> vertices;
					if ( 1 )
					{
						//const unsigned int *src = result.mHullIndices;
						for (unsigned int i=0; i<result.mHullVcount; i++)
						{
							btVector3 vertex(result.mHullVertices[i*3],result.mHullVertices[i*3+1],result.mHullVertices[i*3+2]);
							vertex *= localScaling;
							centroid += vertex;

						}
					}

					centroid *= 1.f/(float(result.mHullVcount) );

					if ( 1 )
					{
						//const unsigned int *src = result.mHullIndices;
						for (unsigned int i=0; i<result.mHullVcount; i++)
						{
							btVector3 vertex(result.mHullVertices[i*3],result.mHullVertices[i*3+1],result.mHullVertices[i*3+2]);
							vertex *= localScaling;
							vertex -= centroid ;
							vertices.push_back(vertex);
						}
					}



					if ( 1 )
					{
						const unsigned int *src = result.mHullIndices;
						for (unsigned int i=0; i<result.mHullTcount; i++)
						{
							unsigned int index0 = *src++;
							unsigned int index1 = *src++;
							unsigned int index2 = *src++;


							btVector3 vertex0(result.mHullVertices[index0*3], result.mHullVertices[index0*3+1],result.mHullVertices[index0*3+2]);
							btVector3 vertex1(result.mHullVertices[index1*3], result.mHullVertices[index1*3+1],result.mHullVertices[index1*3+2]);
							btVector3 vertex2(result.mHullVertices[index2*3], result.mHullVertices[index2*3+1],result.mHullVertices[index2*3+2]);
							vertex0 *= localScaling;
							vertex1 *= localScaling;
							vertex2 *= localScaling;

							vertex0 -= centroid;
							vertex1 -= centroid;
							vertex2 -= centroid;


							trimesh->addTriangle(vertex0,vertex1,vertex2);

							index0+=mBaseCount;
							index1+=mBaseCount;
							index2+=mBaseCount;

							fprintf(mOutputFile,"f %d %d %d\r\n", index0+1, index1+1, index2+1 );
						}
					}

				//	float mass = 1.f;


//this is a tools issue: due to collision margin, convex objects overlap, compensate for it here:
//#define SHRINK_OBJECT_INWARDS 1
#ifdef SHRINK_OBJECT_INWARDS

					float collisionMargin = 0.01f;

					btAlignedObjectArray<btVector3> planeEquations;
					btGeometryUtil::getPlaneEquationsFromVertices(vertices,planeEquations);

					btAlignedObjectArray<btVector3> shiftedPlaneEquations;
					for (int p=0;p<planeEquations.size();p++)
					{
						btVector3 plane = planeEquations[p];
						plane[3] += collisionMargin;
						shiftedPlaneEquations.push_back(plane);
					}
					btAlignedObjectArray<btVector3> shiftedVertices;
					btGeometryUtil::getVerticesFromPlaneEquations(shiftedPlaneEquations,shiftedVertices);


					btConvexHullShape* convexShape = new btConvexHullShape(&(shiftedVertices[0].getX()),shiftedVertices.size());

#else //SHRINK_OBJECT_INWARDS

					btConvexHullShape* convexShape = new btConvexHullShape(&(vertices[0].getX()),vertices.size());
#endif
					if (sEnableSAT)
						convexShape->initializePolyhedralFeatures();
					convexShape->setMargin(0.01f);
					m_convexShapes.push_back(convexShape);
					m_convexCentroids.push_back(centroid);
					m_convexDemo->m_collisionShapes.push_back(convexShape);
					mBaseCount+=result.mHullVcount; // advance the 'base index' counter.


				}
			}

			int   	mBaseCount;
  			int		mHullCount;
			FILE*	mOutputFile;

	};

	if (tcount)
	{
		btTriangleMesh* trimesh = new btTriangleMesh();
		m_trimeshes.push_back(trimesh);

		btVector3 localScaling(6.f,6.f,6.f);

		int i;
		for ( i=0;i<wo.mTriCount;i++)
		{
			int index0 = wo.mIndices[i*3];
			int index1 = wo.mIndices[i*3+1];
			int index2 = wo.mIndices[i*3+2];

			btVector3 vertex0(wo.mVertices[index0*3], wo.mVertices[index0*3+1],wo.mVertices[index0*3+2]);
			btVector3 vertex1(wo.mVertices[index1*3], wo.mVertices[index1*3+1],wo.mVertices[index1*3+2]);
			btVector3 vertex2(wo.mVertices[index2*3], wo.mVertices[index2*3+1],wo.mVertices[index2*3+2]);

			vertex0 *= localScaling;
			vertex1 *= localScaling;
			vertex2 *= localScaling;

			trimesh->addTriangle(vertex0,vertex1,vertex2);
		}


		btConvexShape* tmpConvexShape = new btConvexTriangleMeshShape(trimesh);

		printf("old numTriangles= %d\n",wo.mTriCount);
		printf("old numIndices = %d\n",wo.mTriCount*3);
		printf("old numVertices = %d\n",wo.mVertexCount);

		printf("reducing vertices by creating a convex hull\n");

		//create a hull approximation
		btShapeHull* hull = new btShapeHull(tmpConvexShape);
		btScalar margin = tmpConvexShape->getMargin();
		hull->buildHull(margin);
		tmpConvexShape->setUserPointer(hull);


		printf("new numTriangles = %d\n", hull->numTriangles ());
		printf("new numIndices = %d\n", hull->numIndices ());
		printf("new numVertices = %d\n", hull->numVertices ());

		btConvexHullShape* convexShape = new btConvexHullShape();
		bool updateLocalAabb = false;

		for (i=0;i<hull->numVertices();i++)
		{
			convexShape->addPoint(hull->getVertexPointer()[i],updateLocalAabb);
		}
		convexShape->recalcLocalAabb();

		if (sEnableSAT)
			convexShape->initializePolyhedralFeatures();
		delete tmpConvexShape;
		delete hull;



		m_collisionShapes.push_back(convexShape);

		float mass = 1.f;

		btTransform startTransform;
		startTransform.setIdentity();
		startTransform.setOrigin(btVector3(0,2,14));

		localCreateRigidBody(mass, startTransform,convexShape);

		bool useQuantization = true;
		btCollisionShape* concaveShape = new btBvhTriangleMeshShape(trimesh,useQuantization);
		startTransform.setOrigin(convexDecompositionObjectOffset);
		localCreateRigidBody(0.f,startTransform,concaveShape);

		m_collisionShapes.push_back (concaveShape);

	}


	if (tcount)
	{
		//-----------------------------------
		// Bullet Convex Decomposition
		//-----------------------------------

		char outputFileName[512];
  		strcpy(outputFileName,filename);
  		char *dot = strstr(outputFileName,".");
  		if ( dot )
			*dot = 0;
		strcat(outputFileName,"_convex.obj");
  		FILE* outputFile = fopen(outputFileName,"wb");

		unsigned int depth = 5;
		float cpercent     = 5;
		float ppercent     = 15;
		unsigned int maxv  = 16;
		float skinWidth    = 0.0;

		printf("WavefrontObj num triangles read %i\n",tcount);
		ConvexDecomposition::DecompDesc desc;
		desc.mVcount       = wo.mVertexCount;
		desc.mVertices     = wo.mVertices;
		desc.mTcount       = wo.mTriCount;
		desc.mIndices      = (unsigned int *)wo.mIndices;
		desc.mDepth        = depth;
		desc.mCpercent     = cpercent;
		desc.mPpercent     = ppercent;
		desc.mMaxVertices  = maxv;
		desc.mSkinWidth    = skinWidth;

		MyConvexDecomposition	convexDecomposition(outputFile,this);
		desc.mCallback = &convexDecomposition;


		//-----------------------------------------------
		// HACD
		//-----------------------------------------------

		std::vector< HACD::Vec3<HACD::Real> > points;
		std::vector< HACD::Vec3<long> > triangles;

		for(int i=0; i<wo.mVertexCount; i++ )
		{
			int index = i*3;
			HACD::Vec3<HACD::Real> vertex(wo.mVertices[index], wo.mVertices[index+1],wo.mVertices[index+2]);
			points.push_back(vertex);
		}

		for(int i=0;i<wo.mTriCount;i++)
		{
			int index = i*3;
			HACD::Vec3<long> triangle(wo.mIndices[index], wo.mIndices[index+1], wo.mIndices[index+2]);
			triangles.push_back(triangle);
		}


		HACD::HACD myHACD;
		myHACD.SetPoints(&points[0]);
		myHACD.SetNPoints(points.size());
		myHACD.SetTriangles(&triangles[0]);
		myHACD.SetNTriangles(triangles.size());
		myHACD.SetCompacityWeight(0.1);
		myHACD.SetVolumeWeight(0.0);

		// HACD parameters
		// Recommended parameters: 2 100 0 0 0 0
		size_t nClusters = 2;
		double concavity = 100;
		bool invert = false;
		bool addExtraDistPoints = false;
		bool addNeighboursDistPoints = false;
		bool addFacesPoints = false;

		myHACD.SetNClusters(nClusters);                     // minimum number of clusters
		myHACD.SetNVerticesPerCH(100);                      // max of 100 vertices per convex-hull
		myHACD.SetConcavity(concavity);                     // maximum concavity
		myHACD.SetAddExtraDistPoints(addExtraDistPoints);
		myHACD.SetAddNeighboursDistPoints(addNeighboursDistPoints);
		myHACD.SetAddFacesPoints(addFacesPoints);

		myHACD.Compute();
		nClusters = myHACD.GetNClusters();

		myHACD.Save("output.wrl", false);


		//convexDecomposition.performConvexDecomposition(desc);

//		ConvexBuilder cb(desc.mCallback);
//		cb.process(desc);
		//now create some bodies

		if (1)
		{
			btCompoundShape* compound = new btCompoundShape();
			m_collisionShapes.push_back (compound);

			btTransform trans;
			trans.setIdentity();

			for (int c=0;c<nClusters;c++)
			{
				//generate convex result
				size_t nPoints = myHACD.GetNPointsCH(c);
				size_t nTriangles = myHACD.GetNTrianglesCH(c);

				float* vertices = new float[nPoints*3];
				unsigned int* triangles = new unsigned int[nTriangles*3];

				HACD::Vec3<HACD::Real> * pointsCH = new HACD::Vec3<HACD::Real>[nPoints];
				HACD::Vec3<long> * trianglesCH = new HACD::Vec3<long>[nTriangles];
				myHACD.GetCH(c, pointsCH, trianglesCH);

				// points
				for(size_t v = 0; v < nPoints; v++)
				{
					vertices[3*v] = pointsCH[v].X();
					vertices[3*v+1] = pointsCH[v].Y();
					vertices[3*v+2] = pointsCH[v].Z();
				}
				// triangles
				for(size_t f = 0; f < nTriangles; f++)
				{
					triangles[3*f] = trianglesCH[f].X();
					triangles[3*f+1] = trianglesCH[f].Y();
					triangles[3*f+2] = trianglesCH[f].Z();
				}

				delete [] pointsCH;
				delete [] trianglesCH;

				ConvexResult r(nPoints, vertices, nTriangles, triangles);
				convexDecomposition.ConvexDecompResult(r);
			}

			for (int i=0;i<convexDecomposition.m_convexShapes.size();i++)
			{
				btVector3 centroid = convexDecomposition.m_convexCentroids[i];
				trans.setOrigin(centroid);
				btConvexHullShape* convexShape = convexDecomposition.m_convexShapes[i];
				compound->addChildShape(trans,convexShape);

				btRigidBody* body;
				body = localCreateRigidBody( 1.0, trans,convexShape);
			}
/*			for (int i=0;i<convexDecomposition.m_convexShapes.size();i++)
			{

				btVector3 centroid = convexDecomposition.m_convexCentroids[i];
				trans.setOrigin(centroid);
				btConvexHullShape* convexShape = convexDecomposition.m_convexShapes[i];
				compound->addChildShape(trans,convexShape);

				btRigidBody* body;
				body = localCreateRigidBody( 1.0, trans,convexShape);
			}*/

#if 1
			btScalar mass=10.f;
			trans.setOrigin(-convexDecompositionObjectOffset);
			btRigidBody* body = localCreateRigidBody( mass, trans,compound);
			body->setCollisionFlags(body->getCollisionFlags() |   btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK);

			convexDecompositionObjectOffset.setZ(6);
			trans.setOrigin(-convexDecompositionObjectOffset);
			body = localCreateRigidBody( mass, trans,compound);
			body->setCollisionFlags(body->getCollisionFlags() |   btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK);

			convexDecompositionObjectOffset.setZ(-6);
			trans.setOrigin(-convexDecompositionObjectOffset);
			body = localCreateRigidBody( mass, trans,compound);
			body->setCollisionFlags(body->getCollisionFlags() |   btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK);
#endif
		}


		if (outputFile)
			fclose(outputFile);


	}



#ifdef TEST_SERIALIZATION
	//test serializing this

	int maxSerializeBufferSize = 1024*1024*5;

	btDefaultSerializer*	serializer = new btDefaultSerializer(maxSerializeBufferSize);
	m_dynamicsWorld->serialize(serializer);

	FILE* f2 = fopen("testFile.bullet","wb");
	fwrite(serializer->getBufferPointer(),serializer->getCurrentBufferSize(),1,f2);
	fclose(f2);

	exitPhysics();

	//now try again from the loaded file
	setupEmptyDynamicsWorld();
#endif //TEST_SERIALIZATION

#endif //NO_OBJ_TO_BULLET

#ifdef TEST_SERIALIZATION

	btBulletWorldImporter* fileLoader = new btBulletWorldImporter(m_dynamicsWorld);
	//fileLoader->setVerboseMode(true);

	fileLoader->loadFile("testFile.bullet");
	//fileLoader->loadFile("testFile64Double.bullet");
	//fileLoader->loadFile("testFile64Single.bullet");
	//fileLoader->loadFile("testFile32Single.bullet");




#endif //TEST_SERIALIZATION

}
Example #18
0
//--------------------------------------------------------------
void ofxBulletConvexShape::init( ofMesh& aMesh, ofVec3f a_localScaling, bool a_bUseConvexHull ) {
    _centroid.zero();
    btVector3 centroid = btVector3(0, 0, 0);
    btVector3 localScaling( a_localScaling.x, a_localScaling.y, a_localScaling.z );
    
    vector <ofIndexType>	indicies    = aMesh.getIndices();
	vector <ofVec3f>		verticies   = aMesh.getVertices();
	
	if(!a_bUseConvexHull) {
		for(int i = 0; i < verticies.size(); i++) {
			btVector3 tempVec = btVector3(verticies[i].x, verticies[i].y, verticies[i].z);
			tempVec *= localScaling;
			centroid += tempVec;
		}
		centroid /= (float)verticies.size();
		
		vector<btVector3> newVerts;
		for ( int i = 0; i < indicies.size(); i++) {
			btVector3 vertex( verticies[indicies[i]].x, verticies[indicies[i]].y, verticies[indicies[i]].z);
			vertex *= localScaling;
			vertex -= centroid;
			newVerts.push_back(vertex);
		}
		
		btConvexHullShape* convexShape = new btConvexHullShape(&(newVerts[0].getX()), newVerts.size());
		convexShape->setMargin( 0.01f );
        _shape = convexShape;
        _centroid = ofVec3f(centroid.getX(), centroid.getY(), centroid.getZ() );
	} else {
		// HULL Building code from example ConvexDecompositionDemo.cpp //
		btTriangleMesh* trimesh = new btTriangleMesh();
		
		for ( int i = 0; i < indicies.size()/3; i++) {
			int index0 = indicies[i*3];
			int index1 = indicies[i*3+1];
			int index2 = indicies[i*3+2];
			
			btVector3 vertex0( verticies[index0].x, verticies[index0].y, verticies[index0].z );
			btVector3 vertex1( verticies[index1].x, verticies[index1].y, verticies[index1].z );
			btVector3 vertex2( verticies[index2].x, verticies[index2].y, verticies[index2].z );
			
			vertex0 *= localScaling;
			vertex1 *= localScaling;
			vertex2 *= localScaling;
			
			trimesh->addTriangle(vertex0, vertex1, vertex2);
		}
		
		btConvexShape* tmpConvexShape = new btConvexTriangleMeshShape(trimesh);
		
		//create a hull approximation
		btShapeHull* hull = new btShapeHull(tmpConvexShape);
		btScalar margin = tmpConvexShape->getMargin();
		hull->buildHull(margin);
		tmpConvexShape->setUserPointer(hull);
		
		centroid = btVector3(0., 0., 0.);
		for (int i = 0; i < hull->numVertices(); i++) {
			centroid += hull->getVertexPointer()[i];
		}
		centroid /= (float)hull->numVertices();
		
		btConvexHullShape* convexShape = new btConvexHullShape();
		for (int i=0;i<hull->numVertices();i++) {
			convexShape->addPoint(hull->getVertexPointer()[i] - centroid);
		}
		
		delete tmpConvexShape;
		delete hull;
		
        _shape = convexShape;
        _centroid = ofVec3f(centroid.getX(), centroid.getY(), centroid.getZ() );
	}
    
	_bInited	= true;
}
Example #19
0
bool Script_Edge::is_vertex(const QObject *node) const
{
    return  vertex1() == node || vertex2() == node ;
}
Example #20
0
// Loads all the object files as Rigid Bodies into the physics world
void MapLoader::loadMap()
{

	ConvexDecomposition::WavefrontObj wobj;

	// push all the strings for loading objects
	std::string* file;
	
	/*
	file = new std::string("./assets/map/new_objects/structures/barn.obj");
	fileNames.push_back((*file).c_str());
	file = new std::string("./assets/map/new_objects/structures/bench.obj");
	fileNames.push_back((*file).c_str());
	//file = new std::string("./assets/map/new_objects/structures/house.obj");
	//fileNames.push_back((*file).c_str());
	//file = new std::string("./assets/map/new_objects/structures/boat.obj");
	//fileNames.push_back((*file).c_str());
	file = new std::string("./assets/map/new_objects/structures/floating_hottub.obj");
	fileNames.push_back((*file).c_str());
	file = new std::string("./assets/map/new_objects/structures/silo.obj");
	fileNames.push_back((*file).c_str());
	file = new std::string("./assets/map/new_objects/structures/windmill.obj");             
	fileNames.push_back((*file).c_str());
	file = new std::string("./assets/map/new_objects/structures/house_under_construction.obj");     
	fileNames.push_back((*file).c_str());
	//file = new std::string("./assets/map/new_objects/structures/patio.obj");
	//fileNames.push_back((*file).c_str());
	//file = new std::string("./assets/map/new_objects/nature/pumpkin_patch.obj");
	//fileNames.push_back((*file).c_str());
	*/

	int result;
	for (auto const& file : fileNames)
	{
		result = wobj.loadObj(file);
		printf("loading file: %s\n", file);

		// Error loops if the obj file wasn't loaded correctly
		while (!result)
		{
			printf("loading failed \"%s\"\n", file);
		}

		btTriangleMesh* trimesh = new btTriangleMesh();
		int i;
		for (i = 0; i < wobj.mTriCount; i++)
		{
			int index0 = wobj.mIndices[i * 3];
			int index1 = wobj.mIndices[i * 3 + 1];
			int index2 = wobj.mIndices[i * 3 + 2];

			btVector3 vertex0(wobj.mVertices[index0 * 3], wobj.mVertices[index0 * 3 + 1], wobj.mVertices[index0 * 3 + 2]);
			btVector3 vertex1(wobj.mVertices[index1 * 3], wobj.mVertices[index1 * 3 + 1], wobj.mVertices[index1 * 3 + 2]);
			btVector3 vertex2(wobj.mVertices[index2 * 3], wobj.mVertices[index2 * 3 + 1], wobj.mVertices[index2 * 3 + 2]);

			trimesh->addTriangle(vertex0, vertex1, vertex2);
		}

		btBvhTriangleMeshShape* tmpConvexShape = new btBvhTriangleMeshShape(trimesh, false);

		btDefaultMotionState*playerMotionState = new btDefaultMotionState(btTransform(btQuaternion(0, 0, 0, 1), btVector3(0, 0, 0)));
		//btScalar mass = 500;
		//btVector3 playerInertia(0, 0, 0);
		//convexShape->calculateLocalInertia(mass, playerInertia);
		btRigidBody::btRigidBodyConstructionInfo playerRigidBodyCI(0, playerMotionState, tmpConvexShape, btVector3(0, 0, 0));
		btRigidBody* pRigidBody = new btRigidBody(playerRigidBodyCI);
		pRigidBody->setFriction((btScalar)0.5);
		pRigidBody->setDamping((btScalar)100, (btScalar)100);
		pRigidBody->setUserIndex(ClassId::OBSTACLE);
		curWorld->addRigidBody(pRigidBody);

	}

	// Windmill object                                       bottom    top
	
	btCollisionShape* windmill = new btCylinderShape(btVector3(30, 110, 15));
	btDefaultMotionState*playerMotionState = new btDefaultMotionState(btTransform(btQuaternion(0, 0, 0, 1), btVector3(-128, 1, 3)));
	btRigidBody::btRigidBodyConstructionInfo playerRigidBodyCIz(0, playerMotionState, windmill, btVector3(0, 0, 0));
	btRigidBody* pRigidBody = new btRigidBody(playerRigidBodyCIz);
	pRigidBody->setFriction((btScalar)0.5);
	pRigidBody->setDamping((btScalar)100, (btScalar)100);
	pRigidBody->setUserIndex(ClassId::OBSTACLE);
	curWorld->addRigidBody(pRigidBody);

	btCollisionShape* windmill_plat = new btCylinderShape(btVector3(33, 2, 33));
	playerMotionState = new btDefaultMotionState(btTransform(btQuaternion(0, 0, 0, 1), btVector3(-129, 37, 4)));
	btRigidBody::btRigidBodyConstructionInfo platRigidBodyCIy(0, playerMotionState, windmill_plat, btVector3(0, 0, 0));
	pRigidBody = new btRigidBody(platRigidBodyCIy);
	pRigidBody->setFriction((btScalar)0.5);
	pRigidBody->setDamping((btScalar)100, (btScalar)100);
	pRigidBody->setUserIndex(ClassId::OBSTACLE);
	curWorld->addRigidBody(pRigidBody);
	
	// patio
	btCollisionShape* patio = new btBoxShape(btVector3(32, 2, 16));
	playerMotionState = new btDefaultMotionState(btTransform(btQuaternion(0, 0, 0, 1), btVector3(49, 16, 111)));
	btRigidBody::btRigidBodyConstructionInfo patioCI(0, playerMotionState, patio, btVector3(0, 0, 0));
	pRigidBody = new btRigidBody(patioCI);
	pRigidBody->setFriction((btScalar)0.5);
	pRigidBody->setDamping((btScalar)100, (btScalar)100);
	pRigidBody->setUserIndex(ClassId::OBSTACLE);
	curWorld->addRigidBody(pRigidBody);

	patio = new btBoxShape(btVector3(10, 15, 6));
	playerMotionState = new btDefaultMotionState(btTransform(btQuaternion(0, 0, 0, 1), btVector3(31.6, 0, 130)));
	btRigidBody::btRigidBodyConstructionInfo patio4CI(0, playerMotionState, patio, btVector3(0, 0, 0));
	pRigidBody = new btRigidBody(patio4CI);
	pRigidBody->setFriction((btScalar)0.5);
	pRigidBody->setDamping((btScalar)100, (btScalar)100);
	pRigidBody->setUserIndex(ClassId::OBSTACLE);
	curWorld->addRigidBody(pRigidBody);

	patio = new btBoxShape(btVector3(10, 15, 6));
	playerMotionState = new btDefaultMotionState(btTransform(btQuaternion(0, 0, 0, 1), btVector3(69, 0, 130)));
	btRigidBody::btRigidBodyConstructionInfo patio1CI(0, playerMotionState, patio, btVector3(0, 0, 0));
	pRigidBody = new btRigidBody(patio1CI);
	pRigidBody->setFriction((btScalar)0.5);
	pRigidBody->setDamping((btScalar)100, (btScalar)100);
	pRigidBody->setUserIndex(ClassId::OBSTACLE);
	curWorld->addRigidBody(pRigidBody);

	
	patio = new btBoxShape(btVector3(5, 15, 7));
	playerMotionState = new btDefaultMotionState(btTransform(btQuaternion(0, 0, 0, 1), btVector3(15, 0, 101)));
	btRigidBody::btRigidBodyConstructionInfo patio2CI(0, playerMotionState, patio, btVector3(0, 0, 0));
	pRigidBody = new btRigidBody(patio2CI);
	pRigidBody->setFriction((btScalar)0.5);
	pRigidBody->setDamping((btScalar)100, (btScalar)100);
	pRigidBody->setUserIndex(ClassId::OBSTACLE);
	curWorld->addRigidBody(pRigidBody);

	patio = new btBoxShape(btVector3(5, 15, 7));
	playerMotionState = new btDefaultMotionState(btTransform(btQuaternion(0, 0, 0, 1), btVector3(83, 0, 100)));
	btRigidBody::btRigidBodyConstructionInfo patio3CI(0, playerMotionState, patio, btVector3(0, 0, 0));
	pRigidBody = new btRigidBody(patio3CI);
	pRigidBody->setFriction((btScalar)0.5);
	pRigidBody->setDamping((btScalar)100, (btScalar)100);
	pRigidBody->setUserIndex(ClassId::OBSTACLE);
	curWorld->addRigidBody(pRigidBody);


	// Rock
	btCollisionShape* rock = new btCylinderShape(btVector3(7, 11, 7));
	playerMotionState = new btDefaultMotionState(btTransform(btQuaternion(0, 0, 0, 1), btVector3(-15.4, 0, 103)));
	btRigidBody::btRigidBodyConstructionInfo platRigidBodyCI(0, playerMotionState, rock, btVector3(0, 0, 0));
	pRigidBody = new btRigidBody(platRigidBodyCI);
	pRigidBody->setFriction((btScalar)0.5);
	pRigidBody->setDamping((btScalar)100, (btScalar)100);
	pRigidBody->setUserIndex(ClassId::OBSTACLE);
	curWorld->addRigidBody(pRigidBody);

	//boat
	patio = new btBoxShape(btVector3(50, 2, 23));
	playerMotionState = new btDefaultMotionState(btTransform(btQuaternion(0, 0, 0, 1), btVector3(-145, 20, 136)));
	btRigidBody::btRigidBodyConstructionInfo boatCI(0, playerMotionState, patio, btVector3(0, 0, 0));
	pRigidBody = new btRigidBody(boatCI);
	pRigidBody->setFriction((btScalar)0.5);
	pRigidBody->setDamping((btScalar)100, (btScalar)100);
	pRigidBody->setUserIndex(ClassId::OBSTACLE);
	curWorld->addRigidBody(pRigidBody);

	
	// House
	patio = new btBoxShape(btVector3(40, 50, 60));
	playerMotionState = new btDefaultMotionState(btTransform(btQuaternion(0, 0, 0, 1), btVector3(155, 0, 114)));
	btRigidBody::btRigidBodyConstructionInfo houseCI(0, playerMotionState, patio, btVector3(0, 0, 0));
	pRigidBody = new btRigidBody(houseCI);
	pRigidBody->setFriction((btScalar)0.5);
	pRigidBody->setDamping((btScalar)100, (btScalar)100);
	pRigidBody->setUserIndex(ClassId::OBSTACLE);
	curWorld->addRigidBody(pRigidBody);
	

	patio = new btBoxShape(btVector3(22, 2, 60));
	playerMotionState = new btDefaultMotionState(btTransform(btQuaternion(btVector3(0,0,-1), -.60), btVector3(135, 60, 114)));
	btRigidBody::btRigidBodyConstructionInfo roof1(0, playerMotionState, patio, btVector3(0, 0, 0));
	pRigidBody = new btRigidBody(roof1);
	pRigidBody->setFriction((btScalar)0.5);
	pRigidBody->setDamping((btScalar)100, (btScalar)100);
	pRigidBody->setUserIndex(ClassId::OBSTACLE);
	curWorld->addRigidBody(pRigidBody);

	patio = new btBoxShape(btVector3(22, 2, 60));
	playerMotionState = new btDefaultMotionState(btTransform(btQuaternion(btVector3(0, 0, 1), -.60), btVector3(175, 60, 114)));
	btRigidBody::btRigidBodyConstructionInfo roof2(0, playerMotionState, patio, btVector3(0, 0, 0));
	pRigidBody = new btRigidBody(roof2);
	pRigidBody->setFriction((btScalar)0.5);
	pRigidBody->setDamping((btScalar)100, (btScalar)100);
	pRigidBody->setUserIndex(ClassId::OBSTACLE);
	curWorld->addRigidBody(pRigidBody);

	// Construction House
	patio = new btBoxShape(btVector3(36, 9, 55));
	playerMotionState = new btDefaultMotionState(btTransform(btQuaternion(0, 0, 0, 1), btVector3(-141, 0, -121)));
	btRigidBody::btRigidBodyConstructionInfo conH(0, playerMotionState, patio, btVector3(0, 0, 0));
	pRigidBody = new btRigidBody(conH);
	pRigidBody->setFriction((btScalar)0.5);
	pRigidBody->setDamping((btScalar)100, (btScalar)100);
	pRigidBody->setUserIndex(ClassId::OBSTACLE);
	curWorld->addRigidBody(pRigidBody);
	
	patio = new btBoxShape(btVector3(36, 1, 55));
	playerMotionState = new btDefaultMotionState(btTransform(btQuaternion(0, 0, 0, 1), btVector3(-141, 24, -121)));
	btRigidBody::btRigidBodyConstructionInfo conH0(0, playerMotionState, patio, btVector3(0, 0, 0));
	pRigidBody = new btRigidBody(conH0);
	pRigidBody->setFriction((btScalar)0.5);
	pRigidBody->setDamping((btScalar)100, (btScalar)100);
	pRigidBody->setUserIndex(ClassId::OBSTACLE);
	curWorld->addRigidBody(pRigidBody);

	// Silo
	btCollisionShape* silo = new btCylinderShape(btVector3(20, 63, 20));
	playerMotionState = new btDefaultMotionState(btTransform(btQuaternion(0, 0, 0, 1), btVector3(146.5, 0, 4)));
	btRigidBody::btRigidBodyConstructionInfo siloc(0, playerMotionState, silo, btVector3(0, 0, 0));
	pRigidBody = new btRigidBody(siloc);
	pRigidBody->setFriction((btScalar)0.5);
	pRigidBody->setDamping((btScalar)100, (btScalar)100);
	pRigidBody->setUserIndex(ClassId::OBSTACLE);
	curWorld->addRigidBody(pRigidBody);

	// barn
	btCollisionShape* barn = new btBoxShape(btVector3(18, 50, 25));
	playerMotionState = new btDefaultMotionState(btTransform(btQuaternion(0, 0, 0, 1), btVector3(143.6, 0, -54)));
	btRigidBody::btRigidBodyConstructionInfo barnCI(0, playerMotionState, barn, btVector3(0, 0, 0));
	pRigidBody = new btRigidBody(barnCI);
	pRigidBody->setFriction((btScalar)0.5);
	pRigidBody->setDamping((btScalar)100, (btScalar)100);
	pRigidBody->setUserIndex(ClassId::OBSTACLE);
	curWorld->addRigidBody(pRigidBody);

	// barbara
	btCollisionShape* bb = new btBoxShape(btVector3(20, 7, 10));
	playerMotionState = new btDefaultMotionState(btTransform(btQuaternion(0, 0, 0, 1), btVector3(-71, 0, 108)));
	btRigidBody::btRigidBodyConstructionInfo bbCI(0, playerMotionState, bb, btVector3(0, 0, 0));
	pRigidBody = new btRigidBody(bbCI);
	pRigidBody->setFriction((btScalar)0.5);
	pRigidBody->setDamping((btScalar)100, (btScalar)100);
	pRigidBody->setUserIndex(ClassId::OBSTACLE);
	curWorld->addRigidBody(pRigidBody);

	btCollisionShape* bb1 = new btBoxShape(btVector3(20, 2, 10));
	playerMotionState = new btDefaultMotionState(btTransform(btQuaternion(0, 0, 0, 1), btVector3(-71, 17, 108)));
	btRigidBody::btRigidBodyConstructionInfo bbCI1(0, playerMotionState, bb1, btVector3(0, 0, 0));
	pRigidBody = new btRigidBody(bbCI1);
	pRigidBody->setFriction((btScalar)0.5);
	pRigidBody->setDamping((btScalar)100, (btScalar)100);
	pRigidBody->setUserIndex(ClassId::OBSTACLE);
	curWorld->addRigidBody(pRigidBody);
}
Example #21
0
std::vector<DrawCmdData<Vertex_1P1N1UV>> SolidCubeFactory::CreateNormalMesh()
{
	float width = width_/2;
	float height = height_/2;
	float depth = depth_/2;

	DrawCmdData<Vertex_1P1N1UV> cmd;
	cmd.draw_mode = kDrawTriangles;
	DrawCmdData<Vertex_1P1N1UV>::VertexList &vert_list = cmd.vertex_list;
	std::vector<unsigned short> &index_list = cmd.index_list;

	//normal
	{
		// Front Face
		int baseIndex = vert_list.size();
		Vec3 normal(0, 0, +1);

		Vec2 texCoord1(0, 0);	Vec3 vertex1(-width, -height, depth);
		Vec2 texCoord2(1, 0);	Vec3 vertex2( width, -height, depth);
		Vec2 texCoord3(1, 1);	Vec3 vertex3( width,  height, depth);
		Vec2 texCoord4(0, 1);	Vec3 vertex4(-width,  height, depth);

		//add vertex
		Vertex_1P1N1UV v1;  v1.p = vertex1; v1.uv = texCoord1;  v1.n = normal;
		Vertex_1P1N1UV v2;  v2.p = vertex2; v2.uv = texCoord2;  v2.n = normal;
		Vertex_1P1N1UV v3;  v3.p = vertex3; v3.uv = texCoord3;  v3.n = normal;
		Vertex_1P1N1UV v4;  v4.p = vertex4; v4.uv = texCoord4;  v4.n = normal;

		vert_list.push_back(v1);
		vert_list.push_back(v2);
		vert_list.push_back(v3);
		vert_list.push_back(v4);

		//add index
		index_list.push_back(baseIndex + 0);
		index_list.push_back(baseIndex + 1);
		index_list.push_back(baseIndex + 2);

		index_list.push_back(baseIndex + 0);
		index_list.push_back(baseIndex + 2);
		index_list.push_back(baseIndex + 3);
	}
	{
		// Back Face
		int baseIndex = vert_list.size();
		Vec3 normal(0, 0, -1);

		Vec2 texCoord1(1, 0);	Vec3 vertex1(-width, -height, -depth);
		Vec2 texCoord2(1, 1);	Vec3 vertex2(-width,  height, -depth);
		Vec2 texCoord3(0, 1);	Vec3 vertex3( width,  height, -depth);
		Vec2 texCoord4(0, 0);	Vec3 vertex4( width, -height, -depth);

		//add vertex
		Vertex_1P1N1UV v1;  v1.p = vertex1; v1.uv = texCoord1;  v1.n = normal;
		Vertex_1P1N1UV v2;  v2.p = vertex2; v2.uv = texCoord2;  v2.n = normal;
		Vertex_1P1N1UV v3;  v3.p = vertex3; v3.uv = texCoord3;  v3.n = normal;
		Vertex_1P1N1UV v4;  v4.p = vertex4; v4.uv = texCoord4;  v4.n = normal;

		vert_list.push_back(v1);
		vert_list.push_back(v2);
		vert_list.push_back(v3);
		vert_list.push_back(v4);

		//add index
		index_list.push_back(baseIndex + 0);
		index_list.push_back(baseIndex + 1);
		index_list.push_back(baseIndex + 2);

		index_list.push_back(baseIndex + 0);
		index_list.push_back(baseIndex + 2);
		index_list.push_back(baseIndex + 3);
	}

	{
		// Top Face
		int baseIndex = vert_list.size();
		Vec3 normal(0, 1, 0);

		Vec2 texCoord1(0, 1);	Vec3 vertex1(-width, height, -depth);
		Vec2 texCoord2(0, 0);	Vec3 vertex2(-width, height,  depth);
		Vec2 texCoord3(1, 0);	Vec3 vertex3( width, height,  depth);
		Vec2 texCoord4(1, 1);	Vec3 vertex4( width, height, -depth);

		//add vertex
		Vertex_1P1N1UV v1;  v1.p = vertex1; v1.uv = texCoord1;  v1.n = normal;
		Vertex_1P1N1UV v2;  v2.p = vertex2; v2.uv = texCoord2;  v2.n = normal;
		Vertex_1P1N1UV v3;  v3.p = vertex3; v3.uv = texCoord3;  v3.n = normal;
		Vertex_1P1N1UV v4;  v4.p = vertex4; v4.uv = texCoord4;  v4.n = normal;

		vert_list.push_back(v1);
		vert_list.push_back(v2);
		vert_list.push_back(v3);
		vert_list.push_back(v4);

		//add index
		index_list.push_back(baseIndex + 0);
		index_list.push_back(baseIndex + 1);
		index_list.push_back(baseIndex + 2);

		index_list.push_back(baseIndex + 0);
		index_list.push_back(baseIndex + 2);
		index_list.push_back(baseIndex + 3);
	}

	{
		// Bottom Face
		int baseIndex = vert_list.size();
		Vec3 normal(0, -1, 0);

		Vec2 texCoord1(1, 1);	Vec3 vertex1(-width, -height, -depth);
		Vec2 texCoord2(0, 1);	Vec3 vertex2( width, -height, -depth);
		Vec2 texCoord3(0, 0);	Vec3 vertex3( width, -height,  depth);
		Vec2 texCoord4(1, 0);	Vec3 vertex4(-width, -height,  depth);

		//add vertex
		Vertex_1P1N1UV v1;  v1.p = vertex1; v1.uv = texCoord1;  v1.n = normal;
		Vertex_1P1N1UV v2;  v2.p = vertex2; v2.uv = texCoord2;  v2.n = normal;
		Vertex_1P1N1UV v3;  v3.p = vertex3; v3.uv = texCoord3;  v3.n = normal;
		Vertex_1P1N1UV v4;  v4.p = vertex4; v4.uv = texCoord4;  v4.n = normal;

		vert_list.push_back(v1);
		vert_list.push_back(v2);
		vert_list.push_back(v3);
		vert_list.push_back(v4);

		//add index
		index_list.push_back(baseIndex + 0);
		index_list.push_back(baseIndex + 1);
		index_list.push_back(baseIndex + 2);

		index_list.push_back(baseIndex + 0);
		index_list.push_back(baseIndex + 2);
		index_list.push_back(baseIndex + 3);
	}

	{
		// Right face
		int baseIndex = vert_list.size();
		Vec3 normal(1, 0, 0);

		Vec2 texCoord1(1, 0);	Vec3 vertex1(width, -height, -depth);
		Vec2 texCoord2(1, 1);	Vec3 vertex2(width,  height, -depth);
		Vec2 texCoord3(0, 1);	Vec3 vertex3(width,  height,  depth);
		Vec2 texCoord4(0, 0);	Vec3 vertex4(width, -height,  depth);

		//add vertex
		Vertex_1P1N1UV v1;  v1.p = vertex1; v1.uv = texCoord1;  v1.n = normal;
		Vertex_1P1N1UV v2;  v2.p = vertex2; v2.uv = texCoord2;  v2.n = normal;
		Vertex_1P1N1UV v3;  v3.p = vertex3; v3.uv = texCoord3;  v3.n = normal;
		Vertex_1P1N1UV v4;  v4.p = vertex4; v4.uv = texCoord4;  v4.n = normal;

		vert_list.push_back(v1);
		vert_list.push_back(v2);
		vert_list.push_back(v3);
		vert_list.push_back(v4);

		//add index
		index_list.push_back(baseIndex + 0);
		index_list.push_back(baseIndex + 1);
		index_list.push_back(baseIndex + 2);

		index_list.push_back(baseIndex + 0);
		index_list.push_back(baseIndex + 2);
		index_list.push_back(baseIndex + 3);
	}

	{
		// Left Face
		int baseIndex = vert_list.size();
		Vec3 normal(-1, 0, 0);

		Vec2 texCoord1(0, 0);	Vec3 vertex1(-width, -height, -depth);
		Vec2 texCoord2(1, 0);	Vec3 vertex2(-width, -height,  depth);
		Vec2 texCoord3(1, 1);	Vec3 vertex3(-width,  height,  depth);
		Vec2 texCoord4(0, 1);	Vec3 vertex4(-width,  height, -depth);

		//add vertex
		Vertex_1P1N1UV v1;  v1.p = vertex1; v1.uv = texCoord1;  v1.n = normal;
		Vertex_1P1N1UV v2;  v2.p = vertex2; v2.uv = texCoord2;  v2.n = normal;
		Vertex_1P1N1UV v3;  v3.p = vertex3; v3.uv = texCoord3;  v3.n = normal;
		Vertex_1P1N1UV v4;  v4.p = vertex4; v4.uv = texCoord4;  v4.n = normal;

		vert_list.push_back(v1);
		vert_list.push_back(v2);
		vert_list.push_back(v3);
		vert_list.push_back(v4);

		//add index
		index_list.push_back(baseIndex + 0);
		index_list.push_back(baseIndex + 1);
		index_list.push_back(baseIndex + 2);

		index_list.push_back(baseIndex + 0);
		index_list.push_back(baseIndex + 2);
		index_list.push_back(baseIndex + 3);
	}

	std::vector<DrawCmdData<Vertex_1P1N1UV>> data_list;
	data_list.push_back(cmd);
	return data_list;
}
CollisionRenderObject::CollisionRenderObject(DAVA::Entity *entity, btCollisionWorld *word, DAVA::RenderObject *renderObject)
    : CollisionBaseObject(entity, word)
    , btTriangles(NULL)
    , btShape(NULL)
{
    if(NULL != renderObject && NULL != word)
    {
        bool anyPolygonAdded = false;
        DAVA::Matrix4 curEntityTransform = entity->GetWorldTransform();

        DAVA::AABBox3 commonBox;

        int maxVertexCount = 0;
        int bestLodIndex = 0;
        int curSwitchIndex = renderObject->GetSwitchIndex();

        // search for best lod index
        for(DAVA::uint32 i = 0; i < renderObject->GetRenderBatchCount(); ++i)
        {
            int batchLodIndex;
            int batchSwitchIndex;

            DAVA::RenderBatch* batch = renderObject->GetRenderBatch(i, batchLodIndex, batchSwitchIndex);
            int vertexCount = batch->GetPolygonGroup()->GetVertexCount();
            if(vertexCount > maxVertexCount && curSwitchIndex == batchSwitchIndex)
            {
                bestLodIndex = batchLodIndex;
                maxVertexCount = vertexCount;
            }
        }

        for(DAVA::uint32 i = 0; i < renderObject->GetRenderBatchCount(); ++i)
        {
            int batchLodIndex;
            int batchSwitchIndex;

            DAVA::RenderBatch* batch = renderObject->GetRenderBatch(i, batchLodIndex, batchSwitchIndex);
            if(batchLodIndex == bestLodIndex && batchSwitchIndex == curSwitchIndex)
            {
                DAVA::PolygonGroup* pg = batch->GetPolygonGroup();

                if(NULL != pg)
                {
                    // is this the first polygon in cycle
                    if(!anyPolygonAdded)
                    {
                        anyPolygonAdded = true;
                        btTriangles = new btTriangleMesh();
                    }

                    for(int i = 0; i < pg->indexCount; i += 3 )
                    {
                        DAVA::uint16 index0 = pg->indexArray[i];
                        DAVA::uint16 index1 = pg->indexArray[i+1];
                        DAVA::uint16 index2 = pg->indexArray[i+2];

                        DAVA::Vector3 v;
                        pg->GetCoord(index0, v);
                        v = v * curEntityTransform;
                        btVector3 vertex0(v.x, v.y, v.z);

                        pg->GetCoord(index1, v);
                        v = v * curEntityTransform;
                        btVector3 vertex1(v.x, v.y, v.z);

                        pg->GetCoord(index2, v);
                        v = v * curEntityTransform;
                        btVector3 vertex2(v.x, v.y, v.z);

                        btTriangles->addTriangle(vertex0, vertex1, vertex2, false);
                    }

                    // save original bbox
                    boundingBox.AddAABBox(pg->GetBoundingBox());
                }
            }
        }

        if(anyPolygonAdded)
        {
            // increase bbox a a little bit
            boundingBox.AddPoint(boundingBox.min - DAVA::Vector3(0.5f, 0.5f, 0.5f));
            boundingBox.AddPoint(boundingBox.max + DAVA::Vector3(0.5f, 0.5f, 0.5f));

            DAVA::Vector3 pos = curEntityTransform.GetTranslationVector();

            btObject = new btCollisionObject();
            btShape = new btBvhTriangleMeshShape(btTriangles, true, true);

            btObject->setCollisionShape(btShape);
            btWord->addCollisionObject(btObject);
        }
    }
}
Example #23
0
        void MezzConvexDecomposition::ConvexDecompResult(ConvexDecomposition::ConvexResult &result)
        {
            btTriangleMesh* trimesh = new btTriangleMesh();

            btVector3 localScaling(1.f,1.f,1.f);

            //calc centroid, to shift vertices around center of mass
            btVector3 centroid;
            centroid.setValue(0,0,0);

            btAlignedObjectArray<btVector3> vertices;

            //const unsigned int *src = result.mHullIndices;
            for (unsigned int i=0; i<result.mHullVcount; i++)
            {
                    btVector3 vertex(result.mHullVertices[i*3],result.mHullVertices[i*3+1],result.mHullVertices[i*3+2]);
                    vertex *= localScaling;
                    centroid += vertex;
            }

            centroid *= 1.f/(float(result.mHullVcount) );

            //const unsigned int *src = result.mHullIndices;
            for (unsigned int i=0; i<result.mHullVcount; i++)
            {
                btVector3 vertex(result.mHullVertices[i*3],result.mHullVertices[i*3+1],result.mHullVertices[i*3+2]);
                vertex *= localScaling;
                vertex -= centroid ;
                vertices.push_back(vertex);
            }
            const unsigned int *src = result.mHullIndices;
            for (unsigned int i=0; i<result.mHullTcount; i++)
            {
                unsigned int index0 = *src++;
                unsigned int index1 = *src++;
                unsigned int index2 = *src++;

                btVector3 vertex0(result.mHullVertices[index0*3], result.mHullVertices[index0*3+1],result.mHullVertices[index0*3+2]);
                btVector3 vertex1(result.mHullVertices[index1*3], result.mHullVertices[index1*3+1],result.mHullVertices[index1*3+2]);
                btVector3 vertex2(result.mHullVertices[index2*3], result.mHullVertices[index2*3+1],result.mHullVertices[index2*3+2]);
                vertex0 *= localScaling;
                vertex1 *= localScaling;
                vertex2 *= localScaling;

                vertex0 -= centroid;
                vertex1 -= centroid;
                vertex2 -= centroid;

                trimesh->addTriangle(vertex0,vertex1,vertex2);

                index0+=mBaseCount;
                index1+=mBaseCount;
                index2+=mBaseCount;
            }

            btConvexHullShape* convexShape = new btConvexHullShape(&(vertices[0].getX()),vertices.size());

            convexShape->setMargin(0.01f);
            m_convexShapes.push_back(convexShape);
            m_convexCentroids.push_back(centroid);
            mBaseCount+=result.mHullVcount; // advance the 'base index' counter.
        }
void ConvexDecompositionDemo::initPhysics(const char* filename)
{
	setTexturing(true);
	setShadows(true);

	setCameraDistance(26.f);

	ConvexDecomposition::WavefrontObj wo;

	tcount = wo.loadObj(filename);

	if (!tcount)
	{
		//when running this app from visual studio, the default starting folder is different, so make a second attempt...
		tcount = wo.loadObj("../../file.obj");
	}


	m_collisionConfiguration = new btDefaultCollisionConfiguration();

#ifdef USE_PARALLEL_DISPATCHER
#ifdef USE_WIN32_THREADING

	int maxNumOutstandingTasks = 4;//number of maximum outstanding tasks
	Win32ThreadSupport* threadSupport = new Win32ThreadSupport(Win32ThreadSupport::Win32ThreadConstructionInfo(
								"collision",
								processCollisionTask,
								createCollisionLocalStoreMemory,
								maxNumOutstandingTasks));
#else
///@todo other platform threading
///Playstation 3 SPU (SPURS)  version is available through PS3 Devnet
///Libspe2 SPU support will be available soon
///pthreads version
///you can hook it up to your custom task scheduler by deriving from btThreadSupportInterface
#endif

	m_dispatcher = new	SpuGatheringCollisionDispatcher(threadSupport,maxNumOutstandingTasks,m_collisionConfiguration);
#else
	m_dispatcher = new	btCollisionDispatcher(m_collisionConfiguration);
#endif//USE_PARALLEL_DISPATCHER


	convexDecompositionObjectOffset.setValue(10,0,0);

	btVector3 worldAabbMin(-10000,-10000,-10000);
	btVector3 worldAabbMax(10000,10000,10000);

	m_broadphase = new btAxisSweep3(worldAabbMin,worldAabbMax);
	//m_broadphase = new btSimpleBroadphase();

	m_solver = new btSequentialImpulseConstraintSolver();
	m_dynamicsWorld = new btDiscreteDynamicsWorld(m_dispatcher,m_broadphase,m_solver,m_collisionConfiguration);

#ifdef USE_PARALLEL_DISPATCHER
	m_dynamicsWorld->getDispatchInfo().m_enableSPU = true;
#endif //USE_PARALLEL_DISPATCHER

	btTransform startTransform;
	startTransform.setIdentity();
	startTransform.setOrigin(btVector3(0,-4.5,0));

	btCollisionShape* boxShape = new btBoxShape(btVector3(30,2,30));
	m_collisionShapes.push_back(boxShape);
	localCreateRigidBody(0.f,startTransform,boxShape);

	class MyConvexDecomposition : public ConvexDecomposition::ConvexDecompInterface
	{
		ConvexDecompositionDemo*	m_convexDemo;
		
		public:

		btAlignedObjectArray<btConvexHullShape*> m_convexShapes;
		btAlignedObjectArray<btVector3> m_convexCentroids;

		MyConvexDecomposition (FILE* outputFile,ConvexDecompositionDemo* demo)
			:m_convexDemo(demo),
				mBaseCount(0),
			mHullCount(0),
			mOutputFile(outputFile)

		{
		}
		
			virtual void ConvexDecompResult(ConvexDecomposition::ConvexResult &result)
			{

				btTriangleMesh* trimesh = new btTriangleMesh();
				m_convexDemo->m_trimeshes.push_back(trimesh);

				btVector3 localScaling(6.f,6.f,6.f);

				//export data to .obj
				printf("ConvexResult. ");
				if (mOutputFile)
				{
					fprintf(mOutputFile,"## Hull Piece %d with %d vertices and %d triangles.\r\n", mHullCount, result.mHullVcount, result.mHullTcount );

					fprintf(mOutputFile,"usemtl Material%i\r\n",mBaseCount);
					fprintf(mOutputFile,"o Object%i\r\n",mBaseCount);

					for (unsigned int i=0; i<result.mHullVcount; i++)
					{
						const float *p = &result.mHullVertices[i*3];
						fprintf(mOutputFile,"v %0.9f %0.9f %0.9f\r\n", p[0], p[1], p[2] );
					}

					//calc centroid, to shift vertices around center of mass
					centroid.setValue(0,0,0);

					btAlignedObjectArray<btVector3> vertices;
					if ( 1 )
					{
						//const unsigned int *src = result.mHullIndices;
						for (unsigned int i=0; i<result.mHullVcount; i++)
						{
							btVector3 vertex(result.mHullVertices[i*3],result.mHullVertices[i*3+1],result.mHullVertices[i*3+2]);
							vertex *= localScaling;
							centroid += vertex;
							
						}
					}

					centroid *= 1.f/(float(result.mHullVcount) );

					if ( 1 )
					{
						//const unsigned int *src = result.mHullIndices;
						for (unsigned int i=0; i<result.mHullVcount; i++)
						{
							btVector3 vertex(result.mHullVertices[i*3],result.mHullVertices[i*3+1],result.mHullVertices[i*3+2]);
							vertex *= localScaling;
							vertex -= centroid ;
							vertices.push_back(vertex);
						}
					}
					
			

					if ( 1 )
					{
						const unsigned int *src = result.mHullIndices;
						for (unsigned int i=0; i<result.mHullTcount; i++)
						{
							unsigned int index0 = *src++;
							unsigned int index1 = *src++;
							unsigned int index2 = *src++;


							btVector3 vertex0(result.mHullVertices[index0*3], result.mHullVertices[index0*3+1],result.mHullVertices[index0*3+2]);
							btVector3 vertex1(result.mHullVertices[index1*3], result.mHullVertices[index1*3+1],result.mHullVertices[index1*3+2]);
							btVector3 vertex2(result.mHullVertices[index2*3], result.mHullVertices[index2*3+1],result.mHullVertices[index2*3+2]);
							vertex0 *= localScaling;
							vertex1 *= localScaling;
							vertex2 *= localScaling;
							
							vertex0 -= centroid;
							vertex1 -= centroid;
							vertex2 -= centroid;


							trimesh->addTriangle(vertex0,vertex1,vertex2);

							index0+=mBaseCount;
							index1+=mBaseCount;
							index2+=mBaseCount;
							
							fprintf(mOutputFile,"f %d %d %d\r\n", index0+1, index1+1, index2+1 );
						}
					}

					float mass = 1.f;
					//float collisionMargin = 0.01f;

//this is a tools issue: due to collision margin, convex objects overlap, compensate for it here:
//#define SHRINK_OBJECT_INWARDS 1
#ifdef SHRINK_OBJECT_INWARDS

					
					std::vector<btVector3> planeEquations;
					btGeometryUtil::getPlaneEquationsFromVertices(vertices,planeEquations);

					std::vector<btVector3> shiftedPlaneEquations;
					for (int p=0;p<planeEquations.size();p++)
					{
						btVector3 plane = planeEquations[p];
						plane[3] += 5*collisionMargin;
						shiftedPlaneEquations.push_back(plane);
					}
					std::vector<btVector3> shiftedVertices;
					btGeometryUtil::getVerticesFromPlaneEquations(shiftedPlaneEquations,shiftedVertices);

					
					btConvexHullShape* convexShape = new btConvexHullShape(&(shiftedVertices[0].getX()),shiftedVertices.size());
					
#else //SHRINK_OBJECT_INWARDS
					
					btConvexHullShape* convexShape = new btConvexHullShape(&(vertices[0].getX()),vertices.size());
#endif 

					convexShape->setMargin(0.01);
					m_convexShapes.push_back(convexShape);
					m_convexCentroids.push_back(centroid);
					m_convexDemo->m_collisionShapes.push_back(convexShape);
					mBaseCount+=result.mHullVcount; // advance the 'base index' counter.


				}
			}

			int   	mBaseCount;
  			int		mHullCount;
			FILE*	mOutputFile;

	};

	if (tcount)
	{
		btTriangleMesh* trimesh = new btTriangleMesh();
		m_trimeshes.push_back(trimesh);

		btVector3 localScaling(6.f,6.f,6.f);
		
		int i;
		for ( i=0;i<wo.mTriCount;i++)
		{
			int index0 = wo.mIndices[i*3];
			int index1 = wo.mIndices[i*3+1];
			int index2 = wo.mIndices[i*3+2];

			btVector3 vertex0(wo.mVertices[index0*3], wo.mVertices[index0*3+1],wo.mVertices[index0*3+2]);
			btVector3 vertex1(wo.mVertices[index1*3], wo.mVertices[index1*3+1],wo.mVertices[index1*3+2]);
			btVector3 vertex2(wo.mVertices[index2*3], wo.mVertices[index2*3+1],wo.mVertices[index2*3+2]);
			
			vertex0 *= localScaling;
			vertex1 *= localScaling;
			vertex2 *= localScaling;

			trimesh->addTriangle(vertex0,vertex1,vertex2);
		}

		
		btConvexShape* tmpConvexShape = new btConvexTriangleMeshShape(trimesh);
	
		printf("old numTriangles= %d\n",wo.mTriCount);
		printf("old numIndices = %d\n",wo.mTriCount*3);
		printf("old numVertices = %d\n",wo.mVertexCount);
		
		printf("reducing vertices by creating a convex hull\n");

		//create a hull approximation
		btShapeHull* hull = new btShapeHull(tmpConvexShape);
		btScalar margin = tmpConvexShape->getMargin();
		hull->buildHull(margin);
		tmpConvexShape->setUserPointer(hull);
		
		
		printf("new numTriangles = %d\n", hull->numTriangles ());
		printf("new numIndices = %d\n", hull->numIndices ());
		printf("new numVertices = %d\n", hull->numVertices ());
		
		btConvexHullShape* convexShape = new btConvexHullShape();
		for (i=0;i<hull->numVertices();i++)
		{
			convexShape->addPoint(hull->getVertexPointer()[i]);	
		}

		delete tmpConvexShape;
		delete hull;



		m_collisionShapes.push_back(convexShape);

		float mass = 1.f;
		
		btTransform startTransform;
		startTransform.setIdentity();
		startTransform.setOrigin(btVector3(0,2,0));

		localCreateRigidBody(mass, startTransform,convexShape);
		
		bool useQuantization = true;
		btCollisionShape* concaveShape = new btBvhTriangleMeshShape(trimesh,useQuantization);
		startTransform.setOrigin(convexDecompositionObjectOffset);
		localCreateRigidBody(0.f,startTransform,concaveShape);

		m_collisionShapes.push_back (concaveShape);

	}
			

	if (tcount)
	{

		char outputFileName[512];
  		strcpy(outputFileName,filename);
  		char *dot = strstr(outputFileName,".");
  		if ( dot ) 
			*dot = 0;
		strcat(outputFileName,"_convex.obj");
  		FILE* outputFile = fopen(outputFileName,"wb");
				
		unsigned int depth = 5;
		float cpercent     = 5;
		float ppercent     = 15;
		unsigned int maxv  = 16;
		float skinWidth    = 0.0;

		printf("WavefrontObj num triangles read %i\n",tcount);
		ConvexDecomposition::DecompDesc desc;
		desc.mVcount       =	wo.mVertexCount;
		desc.mVertices     = wo.mVertices;
		desc.mTcount       = wo.mTriCount;
		desc.mIndices      = (unsigned int *)wo.mIndices;
		desc.mDepth        = depth;
		desc.mCpercent     = cpercent;
		desc.mPpercent     = ppercent;
		desc.mMaxVertices  = maxv;
		desc.mSkinWidth    = skinWidth;

		MyConvexDecomposition	convexDecomposition(outputFile,this);
		desc.mCallback = &convexDecomposition;
		
		

		//convexDecomposition.performConvexDecomposition(desc);

		ConvexBuilder cb(desc.mCallback);
		cb.process(desc);
		//now create some bodies
		
		{
			btCompoundShape* compound = new btCompoundShape();
			m_collisionShapes.push_back (compound);

			btTransform trans;
			trans.setIdentity();
			for (int i=0;i<convexDecomposition.m_convexShapes.size();i++)
			{
				
				btVector3 centroid = convexDecomposition.m_convexCentroids[i];
				trans.setOrigin(centroid);
				btConvexHullShape* convexShape = convexDecomposition.m_convexShapes[i];
				compound->addChildShape(trans,convexShape);
			}
			btScalar mass=10.f;
			trans.setOrigin(-convexDecompositionObjectOffset);
			localCreateRigidBody( mass, trans,compound);
			convexDecompositionObjectOffset.setZ(6);
			trans.setOrigin(-convexDecompositionObjectOffset);
			localCreateRigidBody( mass, trans,compound);
			convexDecompositionObjectOffset.setZ(-6);
			trans.setOrigin(-convexDecompositionObjectOffset);
			localCreateRigidBody( mass, trans,compound);
			
		}

		
		if (outputFile)
			fclose(outputFile);


	}


	
}
void PointSet::AddControlVolume ( std::vector<glm::vec3> *allvertices )
{
    Vector3DF pos;
	Point* p;	
	int dimx=5;
	int dimy=5;
	float dimz=10;
	int ccnt=0;
	//vec3 a = myvertices. ; 
	glm::vec3 startpoint(0,0.0,-5.0);
	glm::vec3 direction(0,0,1.0);
	glm::vec3 vertex1(0,1.0,2.0);
	glm::vec3 vertex2(-1.0,-1.0,0);
	glm::vec3 vertex3(1.0,-1.0,0);
	glm::vec3 v1,v2,v3;
	int a = allvertices->size();
	double value=0;
	value=PointSet::Test_RayPolyIntersect(startpoint,direction,vertex1,vertex2,vertex3);
	int count=0;
	float var=1.0;
	//glm::vec3 *a = myvertices;
	for (float x = -5; x < 18; x += 1.0)
	{
		for (float y = -5; y <= 14; y += 1.0)
		{	
			 for (float z = -5; z <= 25; z += var )
			 {
				 /*if(z>=-5.0 && z <2.0)
					 var =1.0;
				  else if(z>=2.0 && z < 8.0)
					 var =0.70;
				   else if(z>=8.0 && z < 15.0)
					 var =0.6;
				    else if(z >= 15.0 && z <=25.0)
					 var =0.3;*/

				 count = 0 ;
				 startpoint=glm::vec3((float)x,(float)y,(float)z);

				 direction=glm::vec3(1.0,0.1,0);
				 for(int v=0 ;v < a ; v+=3)
				 {
					 //checking each vertex in the grid with all the 192 triangles of mesh
					 v1=(*allvertices)[v];
					 v2=(*allvertices)[v+1];
					 v3=(*allvertices)[v+2];
					 vertex1= vec3(v1[0],v1[1],v1[2]);
					 vertex2= vec3(v2[0],v2[1],v2[2]);
					 vertex3= vec3(v3[0],v3[1],v3[2]);
					 value=PointSet::Test_RayPolyIntersect(startpoint,direction,vertex1,vertex2,vertex3);
						if(value != -1.0)
						{
							 count++;
						}

				 }

				 //odd
				 if( count % 2 == 1)
				 {
							 //inside the mesh
						p = GetPoint ( AddPointReuse () );
						pos.Set ( x,y,z+10.0f);
						p->pos = pos;	
						p->type = 1;
						p->clr = COLORA( 1.0,0.3,0.3, 0);  ///   0.1,0.3,1.0,1.0 
						
						ccnt++;
				 }
				 //var=var-0.1;
			}
			// var = 1.0;
			 
		}

	}	

}
Example #26
0
void PhysicWorld::initGround(const char* filename)
{
	ConvexDecomposition::WavefrontObj wo;

	btVector3 centroid=btVector3(0,0,0);
	btVector3 convexDecompositionObjectOffset(10,0,0);
	unsigned int tcount = wo.loadObj(filename);


	#ifdef USE_PARALLEL_DISPATCHER
	m_dynamicsWorld->getDispatchInfo().m_enableSPU = true;
	#endif //USE_PARALLEL_DISPATCHER

	class MyConvexDecomposition : public ConvexDecomposition::ConvexDecompInterface
	{
		PhysicWorld*	world;
		btVector3 centroid;

		public:

			btAlignedObjectArray<btConvexHullShape*> m_convexShapes;
			btAlignedObjectArray<btVector3> m_convexCentroids;

			MyConvexDecomposition (FILE* outputFile,PhysicWorld* worldPhysic,btVector3& centre)
			:world(worldPhysic),
			mBaseCount(0),
			mHullCount(0),
			mOutputFile(outputFile),
			centroid(centre)

			{
			}

			virtual void ConvexDecompResult(ConvexDecomposition::ConvexResult &result)
			{

				btTriangleMesh* trimesh = new btTriangleMesh();
				world->m_trimeshes.push_back(trimesh);

				btVector3 localScaling(6.f,6.f,6.f);

				//export data to .obj
				printf("ConvexResult. ");
				if (mOutputFile)
				{
					fprintf(mOutputFile,"## Hull Piece %d with %d vertices and %d triangles.\r\n", mHullCount, result.mHullVcount, result.mHullTcount );

					fprintf(mOutputFile,"usemtl Material%i\r\n",mBaseCount);
					fprintf(mOutputFile,"o Object%i\r\n",mBaseCount);

					for (unsigned int i=0; i<result.mHullVcount; i++)
					{
						const float *p = &result.mHullVertices[i*3];
						fprintf(mOutputFile,"v %0.9f %0.9f %0.9f\r\n", p[0], p[1], p[2] );
					}

					//calc centroid, to shift vertices around center of mass
					centroid.setValue(0,0,0);

					btAlignedObjectArray<btVector3> vertices;
					if ( 1 )
					{
						//const unsigned int *src = result.mHullIndices;
						for (unsigned int i=0; i<result.mHullVcount; i++)
						{
							btVector3 vertex(result.mHullVertices[i*3],result.mHullVertices[i*3+1],result.mHullVertices[i*3+2]);
							vertex *= localScaling;
							centroid += vertex;

						}
					}

					centroid *= 1.f/(float(result.mHullVcount) );

					if ( 1 )
					{
						//const unsigned int *src = result.mHullIndices;
						for (unsigned int i=0; i<result.mHullVcount; i++)
						{
							btVector3 vertex(result.mHullVertices[i*3],result.mHullVertices[i*3+1],result.mHullVertices[i*3+2]);
							vertex *= localScaling;
							vertex -= centroid ;
							vertices.push_back(vertex);
						}
					}



					if ( 1 )
					{
						const unsigned int *src = result.mHullIndices;
						for (unsigned int i=0; i<result.mHullTcount; i++)
						{
							unsigned int index0 = *src++;
							unsigned int index1 = *src++;
							unsigned int index2 = *src++;


							btVector3 vertex0(result.mHullVertices[index0*3], result.mHullVertices[index0*3+1],result.mHullVertices[index0*3+2]);
							btVector3 vertex1(result.mHullVertices[index1*3], result.mHullVertices[index1*3+1],result.mHullVertices[index1*3+2]);
							btVector3 vertex2(result.mHullVertices[index2*3], result.mHullVertices[index2*3+1],result.mHullVertices[index2*3+2]);
							vertex0 *= localScaling;
							vertex1 *= localScaling;
							vertex2 *= localScaling;

							vertex0 -= centroid;
							vertex1 -= centroid;
							vertex2 -= centroid;


							trimesh->addTriangle(vertex0,vertex1,vertex2);

							index0+=mBaseCount;
							index1+=mBaseCount;
							index2+=mBaseCount;

							fprintf(mOutputFile,"f %d %d %d\r\n", index0+1, index1+1, index2+1 );
						}
					}

					float mass = 1.f;
					//float collisionMargin = 0.01f;

					//this is a tools issue: due to collision margin, convex objects overlap, compensate for it here:
					//#define SHRINK_OBJECT_INWARDS 1
					#ifdef SHRINK_OBJECT_INWARDS


					std::vector<btVector3> planeEquations;
					btGeometryUtil::getPlaneEquationsFromVertices(vertices,planeEquations);

					std::vector<btVector3> shiftedPlaneEquations;
					for (int p=0;p<planeEquations.size();p++)
					{
						btVector3 plane = planeEquations[p];
						plane[3] += 5*collisionMargin;
						shiftedPlaneEquations.push_back(plane);
					}
					std::vector<btVector3> shiftedVertices;
					btGeometryUtil::getVerticesFromPlaneEquations(shiftedPlaneEquations,shiftedVertices);


					btConvexHullShape* convexShape = new btConvexHullShape(&(shiftedVertices[0].getX()),shiftedVertices.size());

					#else //SHRINK_OBJECT_INWARDS

						btConvexHullShape* convexShape = new btConvexHullShape(&(vertices[0].getX()),vertices.size());
					#endif 

					convexShape->setMargin(btScalar(0.01));
					m_convexShapes.push_back(convexShape);
					m_convexCentroids.push_back(centroid);
					world->m_collisionShapes.push_back(convexShape);
					mBaseCount+=result.mHullVcount; // advance the 'base index' counter.


				}
			}

			int   	mBaseCount;
			int		mHullCount;
			FILE*	mOutputFile;

	};

	if (tcount)
	{
		btTriangleMesh* trimesh = new btTriangleMesh();
		m_trimeshes.push_back(trimesh);

		btVector3 localScaling(1.f,1.f,1.f);

		int i;
		for ( i=0;i<wo.mTriCount;i++)
		{
			int index0 = wo.mIndices[i*3];
			int index1 = wo.mIndices[i*3+1];
			int index2 = wo.mIndices[i*3+2];

			btVector3 vertex0(wo.mVertices[index0*3], wo.mVertices[index0*3+1],wo.mVertices[index0*3+2]);
			btVector3 vertex1(wo.mVertices[index1*3], wo.mVertices[index1*3+1],wo.mVertices[index1*3+2]);
			btVector3 vertex2(wo.mVertices[index2*3], wo.mVertices[index2*3+1],wo.mVertices[index2*3+2]);

			vertex0 *= localScaling;
			vertex1 *= localScaling;
			vertex2 *= localScaling;

			trimesh->addTriangle(vertex0,vertex1,vertex2);
		}


		btConvexShape* tmpConvexShape = new btConvexTriangleMeshShape(trimesh);

		printf("old numTriangles= %d\n",wo.mTriCount);
		printf("old numIndices = %d\n",wo.mTriCount*3);
		printf("old numVertices = %d\n",wo.mVertexCount);

		printf("reducing vertices by creating a convex hull\n");

		//create a hull approximation
		btShapeHull* hull = new btShapeHull(tmpConvexShape);
		btScalar margin = tmpConvexShape->getMargin();
		hull->buildHull(margin);
		tmpConvexShape->setUserPointer(hull);


		printf("new numTriangles = %d\n", hull->numTriangles ());
		printf("new numIndices = %d\n", hull->numIndices ());
		printf("new numVertices = %d\n", hull->numVertices ());

		btConvexHullShape* convexShape = new btConvexHullShape();
		for (i=0;i<hull->numVertices();i++)
		{
			convexShape->addPoint(hull->getVertexPointer()[i]);	
		}

		delete tmpConvexShape;
		delete hull;



		m_collisionShapes.push_back(convexShape);

		float mass = 1.f;

		/*		btTransform startTransform;
		startTransform.setIdentity();
		startTransform.setOrigin(btVector3(0,2,0));

		localCreateRigidBody(mass, startTransform,convexShape);

		bool useQuantization = true;
		btCollisionShape* concaveShape = new btBvhTriangleMeshShape(trimesh,useQuantization);
		startTransform.setOrigin(convexDecompositionObjectOffset);
		localCreateRigidBody(0.f,startTransform,concaveShape);

		m_collisionShapes.push_back (concaveShape);
		 */
	}


	if (tcount)
	{

		char outputFileName[512];
		strcpy(outputFileName,filename);
		char *dot = strstr(outputFileName,".");
		if ( dot ) 
			*dot = 0;
		strcat(outputFileName,"_convex.obj");
		FILE* outputFile = fopen(outputFileName,"wb");

		unsigned int depth = 5;
		float cpercent     = 5;
		float ppercent     = 15;
		unsigned int maxv  = 16;
		float skinWidth    = 0.0;

		printf("WavefrontObj num triangles read %i\n",tcount);
		ConvexDecomposition::DecompDesc desc;
		desc.mVcount       =	wo.mVertexCount;
		desc.mVertices     = wo.mVertices;
		desc.mTcount       = wo.mTriCount;
		desc.mIndices      = (unsigned int *)wo.mIndices;
		desc.mDepth        = depth;
		desc.mCpercent     = cpercent;
		desc.mPpercent     = ppercent;
		desc.mMaxVertices  = maxv;
		desc.mSkinWidth    = skinWidth;

		MyConvexDecomposition	convexDecomposition(outputFile,this,centroid);
		desc.mCallback = &convexDecomposition;



		//convexDecomposition.performConvexDecomposition(desc);

		ConvexBuilder cb(desc.mCallback);
		cb.process(desc);



		// creation d'un SOL

		{
			btCompoundShape* compound = new btCompoundShape();
			m_collisionShapes.push_back (compound);

			btTransform trans;
			trans.setIdentity();
			for (int i=0;i<convexDecomposition.m_convexShapes.size();i++)
			{

				btVector3 centroid2 = convexDecomposition.m_convexCentroids[i];
				trans.setOrigin(centroid2);
				btConvexHullShape* convexShape = convexDecomposition.m_convexShapes[i];
				compound->addChildShape(trans,convexShape);
			}
			trans.setOrigin(-convexDecompositionObjectOffset);


			btDefaultMotionState* myMotionState = new btDefaultMotionState(trans);	
			btRigidBody::btRigidBodyConstructionInfo rbInfo(0,myMotionState,compound,btVector3(0,0,0));
			m_ground = new btRigidBody(rbInfo);
			this->m_dynamicsWorld->addRigidBody(m_ground);


			//			localCreateRigidBody( btScalar(0.F), trans,compound);
		}


		if (outputFile)
			fclose(outputFile);


	}

}
void convex_decomposition_hacd::ConvexDecompResult(unsigned int hvcount,const float *hvertices,unsigned int htcount,const unsigned int *hindices)
{
   btVector3	centroid=btVector3(0,0,0);
   btVector3   convexDecompositionObjectOffset(10,0,0);

	btTriangleMesh* trimesh = new btTriangleMesh();
	m_trimeshes.push_back(trimesh);

	//calc centroid, to shift vertices around center of mass
	centroid.setValue(0,0,0);

	btAlignedObjectArray<btVector3> vertices;
	if ( 1 )
	{
		//const unsigned int *src = result.mHullIndices;
		for (unsigned int i=0; i<hvcount; i++)
		{
			btVector3 vertex(hvertices[i*3],hvertices[i*3+1],hvertices[i*3+2]);
			centroid += vertex;
		}
	}

	centroid *= 1.f/(float(hvcount) );

	if ( 1 )
	{
		//const unsigned int *src = result.mHullIndices;
		for (unsigned int i=0; i<hvcount; i++)
		{
			btVector3 vertex(hvertices[i*3],hvertices[i*3+1],hvertices[i*3+2]);
			vertex -= centroid ;
			vertices.push_back(vertex);
		}
	}

	if ( 1 )
	{
		const unsigned int *src = hindices;
		for (unsigned int i=0; i<htcount; i++)
		{
			unsigned int index0 = *src++;
			unsigned int index1 = *src++;
			unsigned int index2 = *src++;


			btVector3 vertex0(hvertices[index0*3], hvertices[index0*3+1],hvertices[index0*3+2]);
			btVector3 vertex1(hvertices[index1*3], hvertices[index1*3+1],hvertices[index1*3+2]);
			btVector3 vertex2(hvertices[index2*3], hvertices[index2*3+1],hvertices[index2*3+2]);

			vertex0 -= centroid;
			vertex1 -= centroid;
			vertex2 -= centroid;


			trimesh->addTriangle(vertex0,vertex1,vertex2);

         //added for maya
         mMergedVertices.push_back(vertex0.x()); mMergedVertices.push_back(vertex0.y()); mMergedVertices.push_back(vertex0.z());
         mMergedVertices.push_back(vertex1.x()); mMergedVertices.push_back(vertex1.y()); mMergedVertices.push_back(vertex1.z());
         mMergedVertices.push_back(vertex2.x()); mMergedVertices.push_back(vertex2.y()); mMergedVertices.push_back(vertex2.z());

			index0+=mBaseCount;
			index1+=mBaseCount;
			index2+=mBaseCount;

         mMergedIndices.push_back(index0);
         mMergedIndices.push_back(index1);
         mMergedIndices.push_back(index2);
		}
	}

	btConvexHullShape* convexShape = new btConvexHullShape(&(vertices[0].getX()),vertices.size());

	convexShape->setMargin(0.01f);
	m_convexShapes.push_back(convexShape);
	m_convexCentroids.push_back(centroid);
	mBaseCount+=hvcount; // advance the 'base index' counter.
};
Example #28
0
//--------------------------------------------------------------
bool ofxBulletCustomShape::addMesh( ofMesh a_mesh, ofVec3f a_localScaling, bool a_bUseConvexHull ) {
	if(a_mesh.getMode() != OF_PRIMITIVE_TRIANGLES) {
		ofLog( OF_LOG_ERROR, "ofxBulletCustomShape :: addMesh : mesh must be set to OF_PRIMITIVE_TRIANGLES!! aborting");
		return false;
	}
	if(_bAdded == true) {
		ofLog( OF_LOG_ERROR, "ofxBulletCustomShape :: addMesh : can not call after calling add()" );
		return false;
	}
	
	btVector3 localScaling( a_localScaling.x, a_localScaling.y, a_localScaling.z );
	auto indicies = a_mesh.getIndices();
	auto verticies = a_mesh.getVertices();
    
	btVector3 centroid = btVector3(0, 0, 0);
	
	if(!a_bUseConvexHull) {
		for(int i = 0; i < verticies.size(); i++) {
			btVector3 tempVec = btVector3(verticies[i].x, verticies[i].y, verticies[i].z);
			tempVec *= localScaling;
			centroid += tempVec;
		}
		centroid /= (float)verticies.size();
		
		vector<btVector3> newVerts;
		for ( int i = 0; i < indicies.size(); i++) {
			btVector3 vertex( verticies[indicies[i]].x, verticies[indicies[i]].y, verticies[indicies[i]].z);
			vertex *= localScaling;
			vertex -= centroid;
			newVerts.push_back(vertex);
		}
		
		btConvexHullShape* convexShape = new btConvexHullShape(&(newVerts[0].getX()), newVerts.size());
		convexShape->setMargin( 0.01f );
		shapes.push_back( convexShape );
		centroids.push_back( ofVec3f(centroid.getX(), centroid.getY(), centroid.getZ()) );
	} else {
		// HULL Building code from example ConvexDecompositionDemo.cpp //
		btTriangleMesh* trimesh = new btTriangleMesh();
		
		for ( int i = 0; i < indicies.size()/3; i++) {
			int index0 = indicies[i*3];
			int index1 = indicies[i*3+1];
			int index2 = indicies[i*3+2];
			
			btVector3 vertex0( verticies[index0].x, verticies[index0].y, verticies[index0].z );
			btVector3 vertex1( verticies[index1].x, verticies[index1].y, verticies[index1].z );
			btVector3 vertex2( verticies[index2].x, verticies[index2].y, verticies[index2].z );
			
			vertex0 *= localScaling;
			vertex1 *= localScaling;
			vertex2 *= localScaling;
			
			trimesh->addTriangle(vertex0, vertex1, vertex2);
		}
		
		//cout << "ofxBulletCustomShape :: addMesh : input triangles = " << trimesh->getNumTriangles() << endl;
		//cout << "ofxBulletCustomShape :: addMesh : input indicies = " << indicies.size() << endl;
		//cout << "ofxBulletCustomShape :: addMesh : input verticies = " << verticies.size() << endl;
		
		btConvexShape* tmpConvexShape = new btConvexTriangleMeshShape(trimesh);
		
		//create a hull approximation
		btShapeHull* hull = new btShapeHull(tmpConvexShape);
		btScalar margin = tmpConvexShape->getMargin();
		hull->buildHull(margin);
		tmpConvexShape->setUserPointer(hull);
		
		centroid = btVector3(0., 0., 0.);
		for (int i = 0; i < hull->numVertices(); i++) {
			centroid += hull->getVertexPointer()[i];
		}
		centroid /= (float)hull->numVertices();
		
		//printf("ofxBulletCustomShape :: addMesh : new hull numTriangles = %d\n", hull->numTriangles());
		//printf("ofxBulletCustomShape :: addMesh : new hull numIndices = %d\n", hull->numIndices());
		//printf("ofxBulletCustomShape :: addMesh : new hull numVertices = %d\n", hull->numVertices());
		
		btConvexHullShape* convexShape = new btConvexHullShape();
		for (int i=0;i<hull->numVertices();i++) {
			convexShape->addPoint(hull->getVertexPointer()[i] - centroid);
		}
		
		delete tmpConvexShape;
		delete hull;
		
		shapes.push_back( convexShape );
		centroids.push_back( ofVec3f(centroid.getX(), centroid.getY(), centroid.getZ()) );
	}
	return true;
}
Example #29
0
QObject *Script_Edge::other(QObject *node)
{
    return node == vertex1() ? vertex2() : vertex1();
}
Example #30
0
			virtual void ConvexDecompResult(ConvexDecomposition::ConvexResult &result)
			{

				TriangleMesh* trimesh = new TriangleMesh();

				SimdVector3 localScaling(6.f,6.f,6.f);

				//export data to .obj
				printf("ConvexResult\n");
				if (mOutputFile)
				{
					fprintf(mOutputFile,"## Hull Piece %d with %d vertices and %d triangles.\r\n", mHullCount, result.mHullVcount, result.mHullTcount );

					fprintf(mOutputFile,"usemtl Material%i\r\n",mBaseCount);
					fprintf(mOutputFile,"o Object%i\r\n",mBaseCount);

					for (unsigned int i=0; i<result.mHullVcount; i++)
					{
						const float *p = &result.mHullVertices[i*3];
						fprintf(mOutputFile,"v %0.9f %0.9f %0.9f\r\n", p[0], p[1], p[2] );
					}

					//calc centroid, to shift vertices around center of mass
					centroids[numObjects] = SimdVector3(0,0,0);
					if ( 1 )
					{
						const unsigned int *src = result.mHullIndices;
						for (unsigned int i=0; i<result.mHullTcount; i++)
						{
							unsigned int index0 = *src++;
							unsigned int index1 = *src++;
							unsigned int index2 = *src++;
							SimdVector3 vertex0(result.mHullVertices[index0*3], result.mHullVertices[index0*3+1],result.mHullVertices[index0*3+2]);
							SimdVector3 vertex1(result.mHullVertices[index1*3], result.mHullVertices[index1*3+1],result.mHullVertices[index1*3+2]);
							SimdVector3 vertex2(result.mHullVertices[index2*3], result.mHullVertices[index2*3+1],result.mHullVertices[index2*3+2]);
							vertex0 *= localScaling;
							vertex1 *= localScaling;
							vertex2 *= localScaling;
							centroids[numObjects] += vertex0;
							centroids[numObjects]+= vertex1;
							centroids[numObjects]+= vertex2;
							
						}
					}

					centroids[numObjects] *= 1.f/(float(result.mHullTcount) * 3);

					if ( 1 )
					{
						const unsigned int *src = result.mHullIndices;
						for (unsigned int i=0; i<result.mHullTcount; i++)
						{
							unsigned int index0 = *src++;
							unsigned int index1 = *src++;
							unsigned int index2 = *src++;


							SimdVector3 vertex0(result.mHullVertices[index0*3], result.mHullVertices[index0*3+1],result.mHullVertices[index0*3+2]);
							SimdVector3 vertex1(result.mHullVertices[index1*3], result.mHullVertices[index1*3+1],result.mHullVertices[index1*3+2]);
							SimdVector3 vertex2(result.mHullVertices[index2*3], result.mHullVertices[index2*3+1],result.mHullVertices[index2*3+2]);
							vertex0 *= localScaling;
							vertex1 *= localScaling;
							vertex2 *= localScaling;
							
							vertex0 -= centroids[numObjects];
							vertex1 -= centroids[numObjects];
							vertex2 -= centroids[numObjects];

							trimesh->AddTriangle(vertex0,vertex1,vertex2);

							index0+=mBaseCount;
							index1+=mBaseCount;
							index2+=mBaseCount;
							
							fprintf(mOutputFile,"f %d %d %d\r\n", index0+1, index1+1, index2+1 );
						}
					}

					shapeIndex[numObjects] = numObjects;
					shapePtr[numObjects++] = new ConvexTriangleMeshShape(trimesh);
					
					mBaseCount+=result.mHullVcount; // advance the 'base index' counter.


				}
			}