int main (int argc, char **argv)
{
  // setup pointers to drawstuff callback functions
  dsFunctions fn;
  fn.version = DS_VERSION;
  fn.start = &start;
  fn.step = &simLoop;
  fn.command = &command;
  fn.stop = 0;
  fn.path_to_textures = DRAWSTUFF_TEXTURE_PATH;
  if(argc==2)
    {
        fn.path_to_textures = argv[1];
    }

  // create world
  dInitODE2(0);
  world = dWorldCreate();
 
  space = dSimpleSpaceCreate(0);
  contactgroup = dJointGroupCreate (0);
  dWorldSetGravity (world,0,0,-0.5);
  dWorldSetCFM (world,1e-5);
  dCreatePlane (space,0,0,1,0);
  memset (obj,0,sizeof(obj));

  // note: can't share tridata if intending to trimesh-trimesh collide
  TriData1 = dGeomTriMeshDataCreate();
  dGeomTriMeshDataBuildSingle(TriData1, &Vertices[0], 3 * sizeof(float), VertexCount, (dTriIndex*)&Indices[0], IndexCount, 3 * sizeof(dTriIndex));
  TriData2 = dGeomTriMeshDataCreate();
  dGeomTriMeshDataBuildSingle(TriData2, &Vertices[0], 3 * sizeof(float), VertexCount, (dTriIndex*)&Indices[0], IndexCount, 3 * sizeof(dTriIndex));
  
  TriMesh1 = dCreateTriMesh(space, TriData1, 0, 0, 0);
  TriMesh2 = dCreateTriMesh(space, TriData2, 0, 0, 0);
  dGeomSetData(TriMesh1, TriData1);
  dGeomSetData(TriMesh2, TriData2);
  
  {dGeomSetPosition(TriMesh1, 0, 0, 0.9);
  dMatrix3 Rotation;
  dRFromAxisAndAngle(Rotation, 1, 0, 0, M_PI / 2);
  dGeomSetRotation(TriMesh1, Rotation);}

  {dGeomSetPosition(TriMesh2, 1, 0, 0.9);
  dMatrix3 Rotation;
  dRFromAxisAndAngle(Rotation, 1, 0, 0, M_PI / 2);
  dGeomSetRotation(TriMesh2, Rotation);}
  
  // run simulation
  dsSimulationLoop (argc,argv,352,288,&fn);

  dJointGroupDestroy (contactgroup);
  dSpaceDestroy (space);
  dWorldDestroy (world);
  dCloseODE();
  return 0;
}
示例#2
0
//==============================================================================
OdeMesh::OdeMesh(
    const OdeCollisionObject* parent,
    const aiScene* scene,
    const Eigen::Vector3d& scale)
  : OdeGeom(parent),
    mOdeTriMeshDataId(nullptr)
{
  // Fill vertices, normals, and indices in the ODE friendly data structures.
  fillArrays(scene, scale);

  /// This will hold the vertex data of the triangle mesh
  if (!mOdeTriMeshDataId)
    mOdeTriMeshDataId = dGeomTriMeshDataCreate();

  // Build the ODE triangle mesh
  dGeomTriMeshDataBuildDouble1(
      mOdeTriMeshDataId,
      mVertices.data(),
      3*sizeof(double),
      static_cast<int>(mVertices.size()),
      mIndices.data(),
      static_cast<int>(mIndices.size()),
      3*sizeof(int),
      mNormals.data());

  mGeomId = dCreateTriMesh(0, mOdeTriMeshDataId, nullptr, nullptr, nullptr);
}
示例#3
0
void Obstacle::on_addToScene()
{
    node_ = SceneGraph::addModel(name_, model_);
    size_t batchCnt = 0;
    TriangleBatch const *triBatch = model_->batches(&batchCnt);
    size_t boneCnt = 0;
    Bone const *bone = model_->bones(&boneCnt);
    size_t vSize = model_->vertexSize();
    char const * vertex = (char const *)model_->vertices();
    unsigned int const *index = (unsigned int const *)model_->indices();
    for (size_t bi = 0; bi != batchCnt; ++bi)
    {
        dTriMeshDataID tmd = dGeomTriMeshDataCreate();
        dGeomTriMeshDataBuildSingle(tmd, vertex, vSize, triBatch[bi].maxVertexIndex + 1, 
            index + triBatch[bi].firstTriangle * 3, triBatch[bi].numTriangles * 3, 12);
        dGeomID geom = dCreateTriMesh(gStaticSpace, tmd, 0, 0, 0);
        tmd_.push_back(tmd);
        geom_.push_back(geom);
        Matrix bx;
        get_bone_transform(bone, triBatch[bi].bone, bx);
        Vec3 p(bx.translation());
        addTo(p, pos());
        dGeomSetPosition(geom, p.x, p.y, p.z);
        dGeomSetRotation(geom, bx.rows[0]);
    }
}
示例#4
0
    void cPhysicsObject::CreateTrimesh(cWorld* pWorld, const std::vector<spitfire::math::cVec3>& coords, const std::vector<unsigned int>& indices, const physvec_t& pos, const physvec_t& rot)
    {
      vVertices = coords;
      vIndices = indices;

      bBody = false;
      bDynamic = false;

      // Trimeshes are static for the moment
      v[0] = 0.0f;
      v[1] = 0.0f;
      v[2] = 0.0f;

      dTriMeshDataID trimeshData = dGeomTriMeshDataCreate();

      const int VertexCount = vVertices.size();
      const int IndexCount = vIndices.size();

      dGeomTriMeshDataBuildSingle(
        trimeshData,
        (const void*)vVertices.data(), sizeof(spitfire::math::cVec3), (int)VertexCount, // Faces
        (const void*)vIndices.data(), (int)IndexCount, 3 * sizeof(uint32_t) // Indices
      );

      geom = dCreateTriMesh(pWorld->GetSpaceStatic(), trimeshData, NULL , NULL , NULL);

      InitCommon(pWorld, pos, rot);
    }
        void Solid::createGeometry(const dSpaceID& i_space)
        {
          /// need to get the correct geometry from volume.
          std::vector< ::Ogre::Vector3> vertices ;
          std::vector<unsigned long>    indices ;
          Ogre::Vector3                 scale(1,1,1) ;        
          
          m_vertices = NULL ;
          m_indices = NULL ;

          InternalMessage("Physic","Physic::Implementation::Ode::Solid::createGeometry trace#0") ;
          getObject()
            ->getTrait<Model::Solid>()
            ->getMesh().getMeshInformation(vertices,indices,scale) ;

          if (vertices.size()>0 && indices.size() > 0)
          {
            m_vertices = new dVector3[vertices.size()];
            m_indices = new dTriIndex[indices.size()];
            
            for(unsigned int vertex_index = 0 ; 
                vertex_index < vertices.size() ; 
                ++vertex_index)
            {
              m_vertices[vertex_index][0] = (dReal)(vertices[vertex_index].x) ;
              m_vertices[vertex_index][1] = (dReal)(vertices[vertex_index].y) ;
              m_vertices[vertex_index][2] = (dReal)(vertices[vertex_index].z) ;
              m_vertices[vertex_index][3] = 0 ;
            }

            for(unsigned int index = 0 ; 
                index < indices.size() ; 
                ++index)
            {
              m_indices[index] = (int)indices[index] ;
            }

            m_data = dGeomTriMeshDataCreate() ;

            dGeomTriMeshDataBuildSimple(m_data,
                                        (dReal*)m_vertices,(int)vertices.size(),
                                        m_indices,(int)indices.size()) ;

            m_geometry1 = dCreateTriMesh(i_space,m_data,0,0,0);
            dGeomSetData(m_geometry1,m_data) ;
            dGeomSetCollideBits(m_geometry1,(unsigned long)Collideable::Solid) ;
            createApproximatedGeometry(i_space) ;
            InternalMessage("Physic","Physic::Implementation::Ode::Solid::createGeometry trace#5") ;
          }
        }
示例#6
0
    void trimesh::create_physical_body(
                    double x, 
                    double y, 
                    double z, 
                    double size_x, 
                    double size_y,
                    double size_z,
                    double mass, 
                    std::vector<double>& vertices_vec,
                    std::vector<int>& indices_vec,
                    const std::string name,
                   manager& mgr)
    {
        world_id = mgr.ode_world();
        space_id = mgr.ode_space();

        //see if the trimesh data is cached so that we don't have to recreate it
        if(name.size() > 0) mesh_data = mgr.trimesh_cache().get_data(name);

        //if it is not cached then we create the trimesh data and put it in the cache
        if(!mesh_data)
        {
            trimesh_data* new_data = create_trimesh_data(vertices_vec, indices_vec);
            if(new_data == 0)
            {
                std::cout << "Error creating trimesh: " << name << std::endl;
                return; //TODO should throw instead...
            }
            mesh_data = trimesh_data_cache::data_ptr(new_data);
            mgr.trimesh_cache().cache_data(name, mesh_data);
        }

        //create the geom using the trimesh data
        geom_id = dCreateTriMesh(mgr.ode_space(),mesh_data->data_id, 0, 0, 0); 

        object::set_geom_data(geom_id);
        //create and position the geom to represent the pysical shape of the rigid body   
        dGeomSetPosition (geom_id, x, y, z); //we position it at the center relative to the body
        //if the mass is greater than 0 then the object is a dynamic mesh
        //so we have to create a rigid body
        if(mass > 0)
        {
            create_rigid_body(x, y, z,  mgr);
            size[0] = size_x;
            size[1] = size_y;
            size[2] = size_z;
            set_mass(mass);
            dGeomSetBody (geom_id, body_id); 
        }
    }
示例#7
0
/*-------------------------------------------------------------------------*\
-  public                                                                 -
\*-------------------------------------------------------------------------*/
void PhysicsTriMeshGeom::onCreate(const PhysicsTriMeshGeom *)
{
    PhysicsTriMeshGeomPtr tmpPtr(*this);
    tmpPtr->id = dCreateTriMesh(0, 0, 0, 0, 0);
    data = 0;
    numVertices = 0;
    numFaces = 0;
    vertexData = 0;
    faceData = 0;
    normalData = 0;
    geoNode=NullFC;
    PhysicsGeomBase::setCategoryBits(dGeomGetCategoryBits(id));
    PhysicsGeomBase::setCollideBits(dGeomGetCollideBits(id));
}
示例#8
0
void StaticWorldObject::AddLeaf(ssgLeaf *leaf, sgVec3 initialpos)
{
  // traverse the triangles
  int cnt = leaf->getNumTriangles() ;
  int nv  = leaf->getNumVertices() ;
//  int nn  = leaf->getNumNormals() ;

  float *vertices = new float[3*nv];
  int   *indices  = new int[3*cnt];

  int i;
  for (i=0; i<nv; i++)
  {
    float *v = leaf->getVertex( i ) ;
    assert(v);
    memcpy(vertices+3*i, v, 3*sizeof(float));
  }
  for (i=0; i<cnt; i++)
  {
    short idx0, idx1, idx2 ;
    leaf->getTriangle( i, &idx0, &idx1, &idx2 ) ;
    indices[3*i+0]=idx0;
    indices[3*i+1]=idx1;
    indices[3*i+2]=idx2;
  }

  dTriMeshDataID data = dGeomTriMeshDataCreate();
  dataids.push_back(data);
  dGeomTriMeshDataBuildSingle
  (
    data, 
    vertices,
    3*sizeof(float), 
    nv, 
    indices,
    cnt*3, 
    3*sizeof(int)
  );
  //fprintf(stderr,"Adding trimesh with %d verts, %d indices\n", nv, cnt*3);
  dGeomID trimesh = dCreateTriMesh(space, data, 0,0,0);
  geomids.push_back(trimesh);
  dGeomSetPosition(trimesh, initialpos[0], initialpos[1], initialpos[2]);
  dMatrix3 R;
  dRFromAxisAndAngle (R, 0,1,0, 0.0);
  dGeomSetRotation (trimesh, R);
  dGeomSetData(trimesh, this);
}
示例#9
0
void CollisionMesh::Finalize()
{
	//create mesh data structure
	meshData = dGeomTriMeshDataCreate();

	//create indices
	int indexlist = new int[TriangleList.size()*3];
	for( int i = 0; i< TriangleList.size()*3; i++)
	{
		indexlist[i] = i;
	}

	//copy over vertex data into buffer
	dReal* vertices = new dReal[TriangleList.size()*9];
	int vi=0;
	for ( int i=0; i<TriangleList.size(); i++ )
	{
		vertices[vi+0] = TriangleList[i].v1.x;
		vertices[vi+1] = TriangleList[i].v1.y;
		vertices[vi+2] = TriangleList[i].v1.z;
		vertices[vi+3] = TriangleList[i].v2.x;
		vertices[vi+4] = TriangleList[i].v2.y;
		vertices[vi+5] = TriangleList[i].v2.z;
		vertices[vi+6] = TriangleList[i].v3.x;
		vertices[vi+7] = TriangleList[i].v3.y;
		vertices[vi+8] = TriangleList[i].v3.z;
		vi += 9;

	}

	dGeomTriMeshDataBuildSingle(meshData, vertices, sizeof(dReal)*3,
		TriangleList.size()*3, 
		(const int*)indexlist, 
		TriangleList.size()*3, 3*sizeof( int ));

	Geom = dCreateTriMesh(solver->GetSpaceID(true, Location.x, Location.y, Location.z), meshData, 0, 0, 0);
	dGeomSetData( Geom, &SurfaceDesc );
	dGeomSetPosition( Geom, Location.x, Location.y, Location.z );
	dMatrix3 R;
	dRFromEulerAngles (R, pitch, -yaw, roll);
	dGeomSetRotation( Geom, R );
	Initialized = true;



}
//===========================================================================
void cODEGenericBody::createDynamicMesh(bool a_staticObject,
                                        const cVector3d& a_offsetPos,
										const cMatrix3d& a_offsetRot)
{
    // create ode dynamic body if object is non static
    if (!a_staticObject)
    {
        m_ode_body = dBodyCreate(m_ODEWorld->m_ode_world);

	    // store pointer to current object
	    dBodySetData (m_ode_body, this);
    }
    m_static = a_staticObject;

    // make sure body image has been defined
    if (m_imageModel == NULL) { return; }

    // check if body image is a mesh
    cMesh* mesh = dynamic_cast<cMesh*>(m_imageModel);
    if (mesh == NULL) { return; }

    // store dynamic model type
    m_typeDynamicCollisionModel = ODE_MODEL_TRIMESH;

    // store dynamic model parameters
    m_paramDynColModel0 = 0.0;
    m_paramDynColModel1 = 0.0;
    m_paramDynColModel2 = 0.0;
    m_posOffsetDynColModel = a_offsetPos;
    m_rotOffsetDynColModel = a_offsetRot;

    // create a table which lists all vertices and triangles
    // these vertices must be of type float and not double!
    // even if we are using the double precision compiled version of ODE !
    int numTriangles = mesh->getNumTriangles(true);

    int vertexCount = mesh->getNumVertices(true);
    m_vertices = new float[3 * vertexCount];

    int indexCount = 3 * numTriangles;
    m_vertexIndices = new int[indexCount];

    // build table of ODE vertices and vertex indices recusevily
    int nIndexOffset = 0;
    int nVerticesCount = 0;
    int nIndexCount = 0;
    int nTriangles = buildMeshTable(mesh, nIndexOffset, nVerticesCount, nIndexCount);

    // build box
    m_ode_triMeshDataID = dGeomTriMeshDataCreate();
    dGeomTriMeshDataBuildSingle(m_ode_triMeshDataID,
                                m_vertices,          // vertex positions
                                3 * sizeof(float),   // size of vertex
                                vertexCount,         // number of vertices
                                m_vertexIndices,     // triangle indices
                                3 * nTriangles,      // number of triangles
                                3 * sizeof(int));

    m_ode_geom = dCreateTriMesh(m_ODEWorld->m_ode_space, m_ode_triMeshDataID, 0, 0, 0);

    // remember the mesh's dTriMeshDataID on its userdata for convenience.
    dGeomSetData(m_ode_geom, m_ode_triMeshDataID);

    // computing bounding box of geometry representation
    m_imageModel->computeBoundaryBox(true);

    // compute dimensions
    cVector3d size = m_imageModel->getBoundaryMax() -
                     m_imageModel->getBoundaryMin();

    // set inertia properties
    if (!m_static)
    {
        dMassSetBox(&m_ode_mass, 1.0, size.x, size.y, size.z);
	    dMassAdjust(&m_ode_mass, m_mass);
	    dBodySetMass(m_ode_body,&m_ode_mass);

        dGeomSetBody(m_ode_geom, m_ode_body);
    }

	// adjust position offset
	dGeomSetPosition (m_ode_geom, a_offsetPos.x, a_offsetPos.y, a_offsetPos.z);

	// adjust orientation offset
	dMatrix3 R;
	R[0]  = a_offsetRot.m[0][0];
	R[1]  = a_offsetRot.m[0][1];
	R[2]  = a_offsetRot.m[0][2];
	R[4]  = a_offsetRot.m[1][0];
	R[5]  = a_offsetRot.m[1][1];
	R[6]  = a_offsetRot.m[1][2];
	R[8]  = a_offsetRot.m[2][0];
	R[9]  = a_offsetRot.m[2][1];
	R[10] = a_offsetRot.m[2][2];
	dGeomSetRotation (m_ode_geom, R);
}
示例#11
0
// called when a key pressed
static void command( int cmd )
{
	int i,k;
	dReal sides[3];
	dMass m;

	cmd = locase( cmd );
	if ( cmd == 'v' || cmd == 'b' || cmd == 'c' || cmd == 's' )
	{
		if ( num < NUM )
		{
			i = num;
			num++;
		}
		else
		{
			i = nextobj;
			nextobj++;
			if ( nextobj >= num ) nextobj = 0;

			// destroy the body and geoms for slot i
			dBodyDestroy( obj[i].body );
			for ( k=0; k < GPB; k++ )
			{
				if ( obj[i].geom[k] ) dGeomDestroy( obj[i].geom[k] );
			}
			memset( &obj[i],0,sizeof( obj[i] ) );
		}

		obj[i].body = dBodyCreate( world );
		for ( k=0; k<3; k++ ) sides[k] = dRandReal()*0.5+0.1;

		dMatrix3 R;
		if ( random_pos )
		{
			dBodySetPosition( obj[i].body,
			                  dRandReal()*2-1,dRandReal()*2-1,dRandReal()+3 );
			dRFromAxisAndAngle( R,dRandReal()*2.0-1.0,dRandReal()*2.0-1.0,
			                    dRandReal()*2.0-1.0,dRandReal()*10.0-5.0 );
		}
		else
		{
			dReal maxheight = 0;
			for ( k=0; k<num; k++ )
			{
				const dReal *pos = dBodyGetPosition( obj[k].body );
				if ( pos[2] > maxheight ) maxheight = pos[2];
			}
			dBodySetPosition( obj[i].body, 0,0,maxheight+1 );
			dRFromAxisAndAngle( R,0,0,1,dRandReal()*10.0-5.0 );
		}
		dBodySetRotation( obj[i].body,R );
		dBodySetData( obj[i].body,( void* )( size_t )i );

		if ( cmd == 'b' )
		{
			dMassSetBox( &m,DENSITY,sides[0],sides[1],sides[2] );
			obj[i].geom[0] = dCreateBox( space,sides[0],sides[1],sides[2] );
		}
		else if ( cmd == 'c' )
		{
			sides[0] *= 0.5;
			dMassSetCapsule( &m,DENSITY,3,sides[0],sides[1] );
			obj[i].geom[0] = dCreateCapsule( space,sides[0],sides[1] );
		}
		else if ( cmd == 's' )
		{
			sides[0] *= 0.5;
			dMassSetSphere( &m,DENSITY,sides[0] );
			obj[i].geom[0] = dCreateSphere( space,sides[0] );
		}
		else  if ( cmd == 'v' )
		{
			obj[i].geom[0] = dCreateConvex( space,
			                                convexBunnyPlanes,
			                                convexBunnyPlaneCount,
			                                convexBunnyPoints,
			                                convexBunnyPointCount,
			                                convexBunnyPolygons );

			/// Use equivalent TriMesh to set mass
			dTriMeshDataID new_tmdata = dGeomTriMeshDataCreate();
			dGeomTriMeshDataBuildSingle( new_tmdata, &Vertices[0], 3 * sizeof( float ), VertexCount,
			                             ( dTriIndex* )&Indices[0], IndexCount, 3 * sizeof( dTriIndex ) );

			dGeomID triMesh = dCreateTriMesh( 0, new_tmdata, 0, 0, 0 );

			dMassSetTrimesh( &m, DENSITY, triMesh );

			dGeomDestroy( triMesh );
			dGeomTriMeshDataDestroy( new_tmdata );

			printf( "mass at %f %f %f\n", m.c[0], m.c[1], m.c[2] );
			dGeomSetPosition( obj[i].geom[0], -m.c[0], -m.c[1], -m.c[2] );
			dMassTranslate( &m, -m.c[0], -m.c[1], -m.c[2] );
		}

		for ( k=0; k < GPB; k++ )
		{
			if ( obj[i].geom[k] ) dGeomSetBody( obj[i].geom[k],obj[i].body );
		}

		dBodySetMass( obj[i].body,&m );
	}

	if ( cmd == ' ' )
	{
		selected++;
		if ( selected >= num ) selected = 0;
		if ( selected < 0 ) selected = 0;
	}
	else if ( cmd == 'd' && selected >= 0 && selected < num )
	{
		dBodyDisable( obj[selected].body );
	}
	else if ( cmd == 'e' && selected >= 0 && selected < num )
	{
		dBodyEnable( obj[selected].body );
	}
	else if ( cmd == 'a' )
	{
		show_aabb ^= 1;
	}
	else if ( cmd == 't' )
	{
		show_contacts ^= 1;
	}
	else if ( cmd == 'r' )
	{
		random_pos ^= 1;
	}
}
示例#12
0
static void command (int cmd)
{
    int i,j,k;
    dReal sides[3];
    dMass m;
    bool setBody = false;

    cmd = locase (cmd);
    if (cmd == 'b' || cmd == 's' || cmd == 'c' || cmd == 'x' || cmd == 'm' || cmd == 'y' || cmd == 'v') {
        if (num < NUM) {
            i = num;
            num++;
        }
        else {
            i = nextobj;
            nextobj++;
            if (nextobj >= num) nextobj = 0;

            // destroy the body and geoms for slot i
            dBodyDestroy (obj[i].body);
            for (k=0; k < GPB; k++) {
                if (obj[i].geom[k]) dGeomDestroy (obj[i].geom[k]);
            }
            memset (&obj[i],0,sizeof(obj[i]));
        }

        obj[i].body = dBodyCreate (world);
        for (k=0; k<3; k++) sides[k] = dRandReal()*0.5+0.1;

        dMatrix3 R;
        if (random_pos) {
            dBodySetPosition (obj[i].body,
                              dRandReal()*2-1,dRandReal()*2-1,dRandReal()+3);
            dRFromAxisAndAngle (R,dRandReal()*2.0-1.0,dRandReal()*2.0-1.0,
                                dRandReal()*2.0-1.0,dRandReal()*10.0-5.0);
        }
        else {
            dReal maxheight = 0;
            for (k=0; k<num; k++) {
                const dReal *pos = dBodyGetPosition (obj[k].body);
                if (pos[2] > maxheight) maxheight = pos[2];
            }
            dBodySetPosition (obj[i].body, 0,0,maxheight+1);
            dRFromAxisAndAngle (R,0,0,1,dRandReal()*10.0-5.0);
        }
        dBodySetRotation (obj[i].body,R);
        dBodySetData (obj[i].body,(void*)(size_t)i);

        if (cmd == 'b') {
            dMassSetBox (&m,DENSITY,sides[0],sides[1],sides[2]);
            obj[i].geom[0] = dCreateBox (space,sides[0],sides[1],sides[2]);
        }
        else if (cmd == 'c') {
            sides[0] *= 0.5;
            dMassSetCapsule (&m,DENSITY,3,sides[0],sides[1]);
            obj[i].geom[0] = dCreateCapsule (space,sides[0],sides[1]);
        } else if (cmd == 'v') {

            dMassSetBox (&m,DENSITY,0.25,0.25,0.25);
            obj[i].geom[0] = dCreateConvex(space,
                                           planes,
                                           planecount,
                                           points,
                                           pointcount,
                                           polygons);
        }
        else if (cmd == 'y') {
            sides[1] *= 0.5;
            dMassSetCylinder (&m,DENSITY,3,sides[0],sides[1]);
            obj[i].geom[0] = dCreateCylinder (space,sides[0],sides[1]);
        }
	else if (cmd == 's') {
            sides[0] *= 0.5;
            dMassSetSphere (&m,DENSITY,sides[0]);
            obj[i].geom[0] = dCreateSphere (space,sides[0]);
        }
        else if (cmd == 'm') {
            dTriMeshDataID new_tmdata = dGeomTriMeshDataCreate();
            dGeomTriMeshDataBuildSingle(new_tmdata, &Vertices[0], 3 * sizeof(float), VertexCount, 
                                        (dTriIndex*)&Indices[0], IndexCount, 3 * sizeof(dTriIndex));
            dGeomTriMeshDataPreprocess2(new_tmdata, (1U << dTRIDATAPREPROCESS_BUILD_FACE_ANGLES), NULL);


            obj[i].geom[0] = dCreateTriMesh(space, new_tmdata, 0, 0, 0);

            // remember the mesh's dTriMeshDataID on its userdata for convenience.
            dGeomSetData(obj[i].geom[0], new_tmdata);

            dMassSetTrimesh( &m, DENSITY, obj[i].geom[0] );
            printf("mass at %f %f %f\n", m.c[0], m.c[1], m.c[2]);
            dGeomSetPosition(obj[i].geom[0], -m.c[0], -m.c[1], -m.c[2]);
            dMassTranslate(&m, -m.c[0], -m.c[1], -m.c[2]);
        }
        else if (cmd == 'x') {

            setBody = true;
            // start accumulating masses for the composite geometries
            dMass m2;
            dMassSetZero (&m);

            dReal dpos[GPB][3];	// delta-positions for composite geometries
            dMatrix3 drot[GPB];
      
            // set random delta positions
            for (j=0; j<GPB; j++)
                for (k=0; k<3; k++)
                    dpos[j][k] = dRandReal()*0.3-0.15;
    
            for (k=0; k<GPB; k++) {
                if (k==0) {
                    dReal radius = dRandReal()*0.25+0.05;
                    obj[i].geom[k] = dCreateSphere (space,radius);
                    dMassSetSphere (&m2,DENSITY,radius);
                } else if (k==1) {
                    obj[i].geom[k] = dCreateBox(space,sides[0],sides[1],sides[2]);
                    dMassSetBox(&m2,DENSITY,sides[0],sides[1],sides[2]);
                } else {
                    dReal radius = dRandReal()*0.1+0.05;
                    dReal length = dRandReal()*1.0+0.1;
                    obj[i].geom[k] = dCreateCapsule(space,radius,length);
                    dMassSetCapsule(&m2,DENSITY,3,radius,length);
                }

                dRFromAxisAndAngle(drot[k],dRandReal()*2.0-1.0,dRandReal()*2.0-1.0,
                                   dRandReal()*2.0-1.0,dRandReal()*10.0-5.0);
                dMassRotate(&m2,drot[k]);
		
                dMassTranslate(&m2,dpos[k][0],dpos[k][1],dpos[k][2]);

                // add to the total mass
                dMassAdd(&m,&m2);

            }
            for (k=0; k<GPB; k++) {
                dGeomSetBody(obj[i].geom[k],obj[i].body);
                dGeomSetOffsetPosition(obj[i].geom[k],
                                       dpos[k][0]-m.c[0],
                                       dpos[k][1]-m.c[1],
                                       dpos[k][2]-m.c[2]);
                dGeomSetOffsetRotation(obj[i].geom[k], drot[k]);
            }
            dMassTranslate(&m,-m.c[0],-m.c[1],-m.c[2]);
            dBodySetMass(obj[i].body,&m);

        }

        if (!setBody) { // avoid calling for composite geometries
            for (k=0; k < GPB; k++)
                if (obj[i].geom[k])
                    dGeomSetBody(obj[i].geom[k],obj[i].body);

            dBodySetMass(obj[i].body,&m);
        }
    }

    if (cmd == ' ') {
        selected++;
        if (selected >= num) selected = 0;
        if (selected < 0) selected = 0;
    }
    else if (cmd == 'd' && selected >= 0 && selected < num) {
        dBodyDisable (obj[selected].body);
    }
    else if (cmd == 'e' && selected >= 0 && selected < num) {
        dBodyEnable (obj[selected].body);
    }
    else if (cmd == 'a') {
        show_aabb ^= 1;
    }
    else if (cmd == 't') {
        show_contacts ^= 1;
    }
    else if (cmd == 'r') {
        random_pos ^= 1;
    }
}
示例#13
0
文件: main.cpp 项目: DanGrise/HugMe
static void createMesh()
{
    int i,k;
    dReal sides[3];
    dMass m;

    loading = 1;
    Sleep(100);
    i = num;
    num++;

    obj[i].body = dBodyCreate (ode_world);
    for (k=0; k<3; k++) sides[k] = dRandReal()*0.5+0.1;

    dMatrix3 R;
    
    dBodySetPosition (obj[i].body,
        dRandReal()*2-1,dRandReal()*2-1,dRandReal()+3);
    dRFromAxisAndAngle (R,dRandReal()*2.0-1.0,dRandReal()*2.0-1.0,
        dRandReal()*2.0-1.0,dRandReal()*10.0-5.0);
    
    dBodySetRotation (obj[i].body,R);
    dBodySetData (obj[i].body,(void*)(size_t)i);

    cMesh* new_object = new cMesh(world); 
    new_object->loadFromFile("resources\\models\\bunny.obj");

    new_object->computeGlobalPositions();
    new_object->createAABBCollisionDetector(true, true);
    new_object->computeAllNormals();

    // set material properties of object
    cMaterial new_material;
    new_material.setStiffness(20.0);
    new_material.setDynamicFriction(0.2);
    new_material.setStaticFriction(0.4);

    new_material.m_ambient.set(0.3, 0.3, 0.8);
    new_material.m_diffuse.set(0.8, 0.8, 0.8);
    new_material.m_specular.set(1.0, 1.0, 1.0);
    new_material.setShininess(100);
    new_object->useMaterial(true, true);
    new_object->setMaterial(new_material, true);
    new_object->useColors(false, true);

    cODEProxy* new_proxy = new cODEProxy(default_proxy);
    new_proxy->enableDynamicProxy(true);
    cursor->setRenderingMode(RENDER_DEVICE);
    new_proxy->m_defaultObject = new_object;
    new_proxy->initialize(world, cursor->m_deviceGlobalPos);
    cursor->m_pointForceAlgos.push_back(new_proxy);

    VertexCount = new_object->getNumVertices(true);
    Vertices = new float[VertexCount*3];

    IndexCount = 3*new_object->getNumTriangles(true);
    Indices = new int[IndexCount];

    // This will hold all the parents we're still searching...
    std::list<cMesh*> meshes_to_descend;
    meshes_to_descend.push_front(new_object);

    // While there are still parent meshes to process
    int cnt = 0;
    int cnt2 = 0;
    while(meshes_to_descend.empty() == 0) {

        // Grab the next parent
        cMesh* cur_mesh = meshes_to_descend.front();
        meshes_to_descend.pop_front();

        // Put all his children on the list of parents to process
        for(unsigned int i=0; i<cur_mesh->getNumChildren(); i++) {

            cGenericObject* cur_object = cur_mesh->getChild(i);

            // Only process cMesh children
            cMesh* cur_mesh = dynamic_cast<cMesh*>(cur_object);
            if (cur_mesh) 
            {
				unsigned int i;
                for (i=0; i<cur_mesh->getNumVertices(false); i++)
                {
                    Vertices[cnt] = cur_mesh->getVertex(i)->getPos().x;
                    Vertices[cnt+1] = cur_mesh->getVertex(i)->getPos().y;
                    Vertices[cnt+2] = cur_mesh->getVertex(i)->getPos().z;
                    cnt+=3;
                }
                for (i=0; i<cur_mesh->getNumTriangles(false); i++)
                {
                    Indices[cnt2] = cur_mesh->getTriangle(i)->getIndexVertex0();
                    Indices[cnt2+1] = cur_mesh->getTriangle(i)->getIndexVertex1();
                    Indices[cnt2+2] = cur_mesh->getTriangle(i)->getIndexVertex2();
                    cnt2+=3;
                }
                meshes_to_descend.push_back(cur_mesh);
            }
        }
    }

    dTriMeshDataID new_tmdata = dGeomTriMeshDataCreate();
    dGeomTriMeshDataBuildSingle(new_tmdata, &Vertices[0], 3 * sizeof(float), VertexCount, Indices, IndexCount, 3 * sizeof(int));

    obj[i].geom[0] = dCreateTriMesh(space, new_tmdata, 0, 0, 0);

    // remember the mesh's dTriMeshDataID on its userdata for convenience.
    dGeomSetData(obj[i].geom[0], new_tmdata);      

    dMassSetBox (&m,DENSITY,sides[0],sides[1],sides[2]);
    
    for (k=0; k < GPB; k++) 
        if (obj[i].geom[k]) dGeomSetBody (obj[i].geom[k],obj[i].body);

    dBodySetMass (obj[i].body,&m);
    
    new_object->setPos(0,0,100);
    new_object->computeGlobalPositions(1);
    objects.push_back(new_object);

    syncPoses();
    world->addChild(new_object);
    loading = 0;
    Sleep(100);
}
示例#14
0
void Physics::perframe(){
	//dWorldStep(worldId);

	return;	//not implemented yet

#ifdef ODE
	for(int i=0; i<level->colliders.size(); i++){
		Object* obj=level->colliders[i];

		if(level->colliders[i]->collideType=="box" || level->colliders[i]->collideType=="cube"){
			
			if(level->colliders[i]->oldCollideType!="box" && level->colliders[i]->oldCollideType!="cube"){
				obj->geomId=dCreateBox(spaceId,obj->collideParameters.x,obj->collideParameters.y,obj->collideParameters.z);
				dGeomSetBody(obj->geomId,obj->bodyId);
				obj->geomIdInit=true;
				level->colliders[i]->oldCollideType=level->colliders[i]->collideType;
			}

			if(obj->boxBuilt){
				float lx=level->colliders[i]->box.px-level->colliders[i]->box.nx;
				float ly=level->colliders[i]->box.py-level->colliders[i]->box.ny;
				float lz=level->colliders[i]->box.pz-level->colliders[i]->box.nz;

				dGeomBoxSetLengths (level->colliders[i]->geomId, lx,  ly, lz);
			}
		}else if(obj->collideType=="sphere"){
			if(obj->oldCollideType!="sphere"){
				obj->geomId=dCreateSphere(spaceId,obj->collideParameters.x);
				dGeomSetBody(obj->geomId,obj->bodyId);
				obj->geomIdInit=true;
			}

		}else if(obj->collideType=="plane"){
			obj->geomId=dCreatePlane(spaceId,obj->collideParameters.x,obj->collideParameters.x,obj->collideParameters.x,obj->collideParameters.x);

		}else if(obj->collideType=="cylindar"){
			obj->geomId=dCreateCCylinder(spaceId,obj->collideParameters.x,obj->collideParameters.y);

		}else if(obj->collideType=="triangle"){
			if(obj->oldCollideType!="triangle"){
				dTriMeshDataID tridat=dGeomTriMeshDataCreate();

				obj->geomId=dCreateTriMesh (spaceId, tridat,
				NULL,
				NULL,
				NULL);

				dGeomSetBody(obj->geomId,obj->bodyId);
				obj->geomIdInit=true;
				level->colliders[i]->oldCollideType=level->colliders[i]->collideType;
			}
		}

		if(obj->collide){
			dGeomEnable(obj->geomId);
		}else{
			dGeomDisable(obj->geomId);
		}

		for(int j=0; j<level->colliders.size(); j++){

			if(!level->colliders[i]->geomIdInit || !level->colliders[j]->geomIdInit){
				continue;
			}

			dContactGeom contactg[2];

			int cnt=dCollide(level->colliders[i]->geomId,level->colliders[j]->geomId,0,contactg,sizeof(dContactGeom));

			if(cnt>0){
				dSurfaceParameters surf;
	
				surf.mode=0;
				surf.mode=dContactBounce;
				surf.mu=level->colliders[i]->friction;
				surf.bounce=level->colliders[i]->bounce;
				surf.bounce_vel=level->colliders[i]->bounceThreshold;

				dContact contact;
				contact.geom=contactg[0];
				contact.surface=surf;

				dJointID joint=dJointCreateContact(worldId,0,&contact);

				if(!level->colliders[i]->dynamic){

					dJointAttach(joint,level->colliders[j]->bodyId,0);
				}else if(!level->colliders[j]->dynamic){

					dJointAttach(joint,level->colliders[i]->bodyId,0);
				}else{

					dJointAttach(joint,level->colliders[i]->bodyId,level->colliders[j]->bodyId);
				}
			}
		}
	}

	dWorldSetGravity(worldId,gravity.x,gravity.y,gravity.z);
	dWorldQuickStep(worldId,1);

	for(int i=0; i<level->dynamicObjects.size(); i++){

		if(!level->dynamicObjects[i]->bodyIdInit){
			continue;
		}

		if(level->dynamicObjects[i]->dynamic){
			dBodyEnable(level->dynamicObjects[i]->bodyId);
		}else{
			dBodyDisable(level->dynamicObjects[i]->bodyId);
		}


		const dReal* pos=new dReal[3];

		pos=dBodyGetPosition(level->dynamicObjects[i]->bodyId);

		level->dynamicObjects[i]->pos.x=pos[0];
		level->dynamicObjects[i]->pos.y=pos[1];
		level->dynamicObjects[i]->pos.z=pos[2];

		const dReal* rot=new dReal[3];
		rot=dBodyGetRotation(level->dynamicObjects[i]->bodyId);

		level->dynamicObjects[i]->rot.x=rot[0];
		level->dynamicObjects[i]->rot.y=rot[1];
		level->dynamicObjects[i]->rot.z=rot[2];
	}
#endif
}
示例#15
0
int main (int argc, char **argv)
{
  dMass m;
  dMatrix3 R;

  // setup pointers to drawstuff callback functions
  dsFunctions fn;
  fn.version = DS_VERSION;
  fn.start = &start;
  fn.step = &simLoop;
  fn.command = &command;
  fn.stop = 0;
  fn.path_to_textures = DRAWSTUFF_TEXTURE_PATH;
  if(argc==2)
    {
        fn.path_to_textures = argv[1];
    }

  // create world
  dInitODE2(0);
  world = dWorldCreate();
  space = dHashSpaceCreate (0);
  contactgroup = dJointGroupCreate (0);
  dWorldSetGravity (world,0,0,-9.8);
  dWorldSetQuickStepNumIterations (world, 12);


  // Create a static world using a triangle mesh that we can collide with.
  int numv = sizeof(world_vertices)/(3*sizeof(float));
  int numi = sizeof(world_indices)/ sizeof(dTriIndex);
  printf("numv=%d, numi=%d\n", numv, numi);
  dTriMeshDataID Data = dGeomTriMeshDataCreate();

  dGeomTriMeshDataBuildSingle
  (
    Data, 
    world_vertices, 
    3 * sizeof(float), 
    numv, 
    world_indices, 
    numi, 
    3 * sizeof(dTriIndex)
  );

  world_mesh = dCreateTriMesh(space, Data, 0, 0, 0);
  dGeomSetPosition(world_mesh, 0, 0, 0.5);
  dRFromAxisAndAngle (R, 0,1,0, 0.0);
  dGeomSetRotation (world_mesh, R);


#ifdef BOX
  boxbody = dBodyCreate (world);
  dMassSetBox (&m,1, BOXSZ, BOXSZ, BOXSZ);
  dMassAdjust (&m, 1);
  dBodySetMass (boxbody,&m);
  boxgeom = dCreateBox (0, BOXSZ, BOXSZ, BOXSZ);
  dGeomSetBody (boxgeom,boxbody);
  dSpaceAdd (space, boxgeom);
#endif
#ifdef CYL
  cylbody = dBodyCreate (world);
  dMassSetSphere (&m,1,RADIUS);
  dMassAdjust (&m,WMASS);
  dBodySetMass (cylbody,&m);
  cylgeom = dCreateCylinder(0, RADIUS, WHEELW);
  dGeomSetBody (cylgeom,cylbody);
  
  #if defined(CYL_GEOM_OFFSET)
  dMatrix3 mat;
  dRFromAxisAndAngle(mat,1.0f,0.0f,0.0f,M_PI/2.0);
  dGeomSetOffsetRotation(cylgeom,mat);
  #endif
    
  dSpaceAdd (space, cylgeom);
#endif
  reset_state();

  // run simulation
  dsSimulationLoop (argc,argv,352,288,&fn);

  dJointGroupEmpty (contactgroup);
  dJointGroupDestroy (contactgroup);

  // First destroy geoms, then space, then the world.
#ifdef CYL
  dGeomDestroy (cylgeom);
#endif
#ifdef BOX
  dGeomDestroy (boxgeom);
#endif
  dGeomDestroy (world_mesh);

  dSpaceDestroy (space);
  dWorldDestroy (world);
  dCloseODE();
  return 0;
  (void)world_normals; // get rid of compiler warnings
}
示例#16
0
文件: space.cpp 项目: antoineB/vroom
dGeomID Space::addTriMesh(dTriMeshDataID data/*,dTriCallback *Callback=NULL,
		   dTriArrayCallback *ArrayCallback=NULL,
		   dTriRayCallback *RayCallback=NULL*/){
  //  return dCreateTriMesh (space, data, Callback, ArrayCallback, RayCallback);
  return dCreateTriMesh (space, data, NULL, NULL, NULL);
}
示例#17
0
dGeomID TriMeshInfo::createGeom(dSpaceID space)
{
    return dCreateTriMesh(space, meshID, NULL, NULL, NULL);
}
示例#18
0
int main (int argc, char **argv)
{
  // setup pointers to drawstuff callback functions
  dsFunctions fn;
  fn.version = DS_VERSION;
  fn.start = &start;
  fn.step = &simLoop;
  fn.command = &command;
  fn.stop = 0;
  fn.path_to_textures = DRAWSTUFF_TEXTURE_PATH;

  // create world
  dInitODE2(0);
  world = dWorldCreate();
 
  space = dSimpleSpaceCreate(0);
  contactgroup = dJointGroupCreate (0);
  dWorldSetGravity (world,0,0,-0.5);
  dWorldSetCFM (world,1e-5);
  dCreatePlane (space,0,0,1,0);
  memset (obj,0,sizeof(obj));

  // note: can't share tridata if intending to trimesh-trimesh collide
  const unsigned preprocessFlags = (1U << dTRIDATAPREPROCESS_BUILD_CONCAVE_EDGES) | (1U << dTRIDATAPREPROCESS_BUILD_FACE_ANGLES);
  TriData1 = dGeomTriMeshDataCreate();
  dGeomTriMeshDataBuildSingle(TriData1, &Vertices[0], 3 * sizeof(float), VertexCount, (dTriIndex*)&Indices[0], IndexCount, 3 * sizeof(dTriIndex));
  dGeomTriMeshDataPreprocess2(TriData1, preprocessFlags, NULL);
  TriData2 = dGeomTriMeshDataCreate();
  dGeomTriMeshDataBuildSingle(TriData2, &Vertices[0], 3 * sizeof(float), VertexCount, (dTriIndex*)&Indices[0], IndexCount, 3 * sizeof(dTriIndex));
  dGeomTriMeshDataPreprocess2(TriData2, preprocessFlags, NULL);
  
  TriMesh1 = dCreateTriMesh(space, TriData1, 0, 0, 0);
  TriMesh2 = dCreateTriMesh(space, TriData2, 0, 0, 0);
  dGeomSetData(TriMesh1, TriData1);
  dGeomSetData(TriMesh2, TriData2);
  
  {dGeomSetPosition(TriMesh1, 0, 0, 0.9);
  dMatrix3 Rotation;
  dRFromAxisAndAngle(Rotation, 1, 0, 0, M_PI / 2);
  dGeomSetRotation(TriMesh1, Rotation);}

  {dGeomSetPosition(TriMesh2, 1, 0, 0.9);
  dMatrix3 Rotation;
  dRFromAxisAndAngle(Rotation, 1, 0, 0, M_PI / 2);
  dGeomSetRotation(TriMesh2, Rotation);}
  
  dThreadingImplementationID threading = dThreadingAllocateMultiThreadedImplementation();
  dThreadingThreadPoolID pool = dThreadingAllocateThreadPool(4, 0, dAllocateFlagBasicData, NULL);
  dThreadingThreadPoolServeMultiThreadedImplementation(pool, threading);
  // dWorldSetStepIslandsProcessingMaxThreadCount(world, 1);
  dWorldSetStepThreadingImplementation(world, dThreadingImplementationGetFunctions(threading), threading);

  // run simulation
  dsSimulationLoop (argc,argv,352,288,&fn);

  dThreadingImplementationShutdownProcessing(threading);
  dThreadingFreeThreadPool(pool);
  dWorldSetStepThreadingImplementation(world, NULL, NULL);
  dThreadingFreeImplementation(threading);

  dJointGroupDestroy (contactgroup);
  dSpaceDestroy (space);
  dWorldDestroy (world);
  dCloseODE();
  return 0;
}
示例#19
0
void start()
{
    world = dWorldCreate();
    dWorldSetGravity (world,0,0,-9.8);

    contact_group = dJointGroupCreate(0);

    space = dSimpleSpaceCreate (0);


    // first, the ground plane
    // it has to coincide with the plane we have in drawstuff
    ground = dCreatePlane(space, 0, 0, 1, 0);


    // now a ball
    dMass m;
    dMassSetSphere(&m, 0.1, ball_radius);

    ball1_geom = dCreateSphere(space, ball_radius);
    ball1_body = dBodyCreate(world);
    dGeomSetBody(ball1_geom, ball1_body);
    dBodySetMass(ball1_body, &m);

    ball2_geom = dCreateSphere(space, ball_radius);
    ball2_body = dBodyCreate(world);
    dGeomSetBody(ball2_geom, ball2_body);
    dBodySetMass(ball2_body, &m);




    // tracks made out of boxes
    dGeomID trk;
    dMatrix3 r1, r2, r3;
    dVector3 ro = {0, -(0.5*track_gauge + 0.5*track_width), track_elevation};
    dMatrix3 s1, s2, s3;
    dVector3 so = {0, 0.5*track_gauge + 0.5*track_width, track_elevation};

    dRFromAxisAndAngle(r1, 1, 0, 0,  track_angle);
    dRFromAxisAndAngle(r2, 0, 1, 0, -track_incl);
    dMultiply0_333(r3, r2, r1);

    dRFromAxisAndAngle(s1, 1, 0, 0, -track_angle);
    dRFromAxisAndAngle(s2, 0, 1, 0, -track_incl);
    dMultiply0_333(s3, s2, s1);

    trk = dCreateBox(space, track_len, track_width, track_height);
    dGeomSetPosition(trk, ro[0], ro[1] + balls_sep, ro[2]);
    dGeomSetRotation(trk, r3);

    trk = dCreateBox(space, track_len, track_width, track_height);
    dGeomSetPosition(trk, so[0], so[1] + balls_sep, so[2]);
    dGeomSetRotation(trk, s3);



    

    // tracks made out of trimesh
    for (unsigned i=0; i<n_box_verts; ++i) {
        dVector3 p;
        dMultiply0_331(p, s3, box_verts[i]);
        dAddVectors3(p, p, so);
        dCopyVector3(track_verts[i], p);
    }
    // trimesh tracks 2, transform all vertices by s3
    for (unsigned i=0; i<n_box_verts; ++i) {
        dVector3 p;
        dMultiply0_331(p, r3, box_verts[i]);
        dAddVectors3(p, p, ro);
        dCopyVector3(track_verts[n_box_verts + i], p);
    }

    // copy face indices
    for (unsigned i=0; i<n_box_faces; ++i)
        for (unsigned j=0; j<3; ++j) // each face index
            track_faces[3*i+j] = box_faces[3*i+j];
    for (unsigned i=0; i<n_box_faces; ++i)
        for (unsigned j=0; j<3; ++j) // each face index
            track_faces[3*(i + n_box_faces)+j] = box_faces[3*i+j] + n_box_verts;

    mesh_data = dGeomTriMeshDataCreate();
    dGeomTriMeshDataBuildSimple(mesh_data,
                                track_verts[0], n_track_verts,
                                track_faces, 3*n_track_faces);
    mesh_geom = dCreateTriMesh(space, mesh_data, 0, 0, 0);





    resetSim();
    

    // initial camera position
    static float xyz[3] = {-5.9414,-0.4804,2.9800};
    static float hpr[3] = {32.5000,-10.0000,0.0000};
    dsSetViewpoint (xyz,hpr);

    dsSetSphereQuality(3);
}
示例#20
0
int main (int argc, char **argv)
{
  // setup pointers to drawstuff callback functions
  dsFunctions fn;
  fn.version = DS_VERSION;
  fn.start = &start;
  fn.step = &simLoop;
  fn.command = &command;
  fn.stop = 0;
  fn.path_to_textures = DRAWSTUFF_TEXTURE_PATH;

  // create world
  dInitODE2(0);
  world = dWorldCreate();

  space = dSimpleSpaceCreate(0);
  contactgroup = dJointGroupCreate (0);
  dWorldSetGravity (world,0,0,-0.5);
  dWorldSetCFM (world,1e-5);
  //dCreatePlane (space,0,0,1,0);
  memset (obj,0,sizeof(obj));
  
  Size[0] = 5.0f;
  Size[1] = 5.0f;
  Size[2] = 2.5f;
  
  Vertices[0][0] = -Size[0];
  Vertices[0][1] = -Size[1];
  Vertices[0][2] = Size[2];
  
  Vertices[1][0] = Size[0];
  Vertices[1][1] = -Size[1];
  Vertices[1][2] = Size[2];
  
  Vertices[2][0] = Size[0];
  Vertices[2][1] = Size[1];
  Vertices[2][2] = Size[2];
  
  Vertices[3][0] = -Size[0];
  Vertices[3][1] = Size[1];
  Vertices[3][2] = Size[2];
  
  Vertices[4][0] = 0;
  Vertices[4][1] = 0;
  Vertices[4][2] = 0;
  
  Indices[0] = 0;
  Indices[1] = 1;
  Indices[2] = 4;
  
  Indices[3] = 1;
  Indices[4] = 2;
  Indices[5] = 4;
  
  Indices[6] = 2;
  Indices[7] = 3;
  Indices[8] = 4;
  
  Indices[9] = 3;
  Indices[10] = 0;
  Indices[11] = 4;

  dTriMeshDataID Data = dGeomTriMeshDataCreate();

  //dGeomTriMeshDataBuildSimple(Data, (dReal*)Vertices, VertexCount, Indices, IndexCount);
  dGeomTriMeshDataBuildSingle(Data, Vertices[0], 3 * sizeof(float), VertexCount, &Indices[0], IndexCount, 3 * sizeof(dTriIndex));
  dGeomTriMeshDataPreprocess2(Data, (1U << dTRIDATAPREPROCESS_BUILD_FACE_ANGLES), NULL);

  TriMesh = dCreateTriMesh(space, Data, 0, 0, 0);

  //dGeomSetPosition(TriMesh, 0, 0, 1.0);
  
  Ray = dCreateRay(space, 0.9);
  dVector3 Origin, Direction;
  Origin[0] = 0.0;
  Origin[1] = 0;
  Origin[2] = 0.5;
  Origin[3] = 0;
  
  Direction[0] = 0;
  Direction[1] = 1.1f;
  Direction[2] = -1;
  Direction[3] = 0;
  dNormalize3(Direction);
  
  dGeomRaySet(Ray, Origin[0], Origin[1], Origin[2], Direction[0], Direction[1], Direction[2]);
  
  dThreadingImplementationID threading = dThreadingAllocateMultiThreadedImplementation();
  dThreadingThreadPoolID pool = dThreadingAllocateThreadPool(4, 0, dAllocateFlagBasicData, NULL);
  dThreadingThreadPoolServeMultiThreadedImplementation(pool, threading);
  // dWorldSetStepIslandsProcessingMaxThreadCount(world, 1);
  dWorldSetStepThreadingImplementation(world, dThreadingImplementationGetFunctions(threading), threading);

  // run simulation
  dsSimulationLoop (argc,argv,352,288,&fn);

  dThreadingImplementationShutdownProcessing(threading);
  dThreadingFreeThreadPool(pool);
  dWorldSetStepThreadingImplementation(world, NULL, NULL);
  dThreadingFreeImplementation(threading);

  dJointGroupDestroy (contactgroup);
  dSpaceDestroy (space);
  dWorldDestroy (world);
  dCloseODE();
  return 0;
}
示例#21
0
State* init() {
    State* state = new State();
    dInitODE();

    SDL_Init(SDL_INIT_EVERYTHING);

    state->screen = SDL_SetVideoMode(WIDTH, HEIGHT, 32, SDL_OPENGL);
    SDL_WM_SetCaption("Physics", NULL);
    SDL_Flip(state->screen);

    SDL_ShowCursor(SDL_DISABLE);

    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluPerspective(100, (float)WIDTH/HEIGHT, 0.5, 1000);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();

    glEnable(GL_LIGHTING);
    glEnable(GL_LIGHT0);
    GLfloat light_ambient[] = { 1, 1, 1, 1 };
    glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient);
    GLfloat lightpos[] = {0, 4, 0, 1};
    glLightfv(GL_LIGHT0, GL_POSITION, lightpos);

    glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST);
    glShadeModel(GL_SMOOTH);

    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

    glEnable(GL_DEPTH_TEST);

    glEnable(GL_CULL_FACE);

    glClearColor(0, 0, 0, 1);

    state->posx = 0;//21;
    state->posy = 4;//8;
    state->posz = 5;//21;
    state->rotx = 0;
    state->roty = 0;//-40;
    state->rotz = 0;

    state->wkey = false;
    state->akey = false;
    state->skey = false;
    state->dkey = false;
    state->gkey = false;

    state->simSpeed = 60;

    state->carcam = false;

    state->carbodydrawable = new Drawable("objs/carbody.obj");
    state->carwheeldrawable = new Drawable("objs/carwheel.obj");
    state->map = new Drawable("objs/jump2.obj");
    state->cube = new Drawable("objs/cube.obj");
//    state->monkey = new Drawable("objs/monkey.obj");

    state->world = dWorldCreate();
    dWorldSetGravity(state->world, 0, -9.8, 0);

    state->worldSpace = dHashSpaceCreate(0);

    const double carHeight = 0.65;
    const double carZ = 90;
    const double carX = 0;
    const float speed = -1000;
    const float force = 200;

    state->carbodybody = dBodyCreate(state->world);
    dBodySetPosition(state->carbodybody, carX, carHeight, carZ);
    dMass bodymass;
    dMassSetBoxTotal(&bodymass, 100, 2, 4, 1);
    dBodySetMass(state->carbodybody, &bodymass);
    dGeomID carbodygeom = dCreateBox(state->worldSpace, 2, 1, 4);
    dGeomSetBody(carbodygeom, state->carbodybody);

    state->flcarwheelbody = dBodyCreate(state->world);
    dBodySetPosition(state->flcarwheelbody, carX-1.5, carHeight - 0.5, carZ+2);
    const dMatrix3 m = { 0, 0, 1, 0
                       , 0, 1, 0, 0
                       , 0, 0, 1, 0 };
    dBodySetRotation(state->flcarwheelbody, m);
    dMass wheelmass;
    dMassSetCylinder(&wheelmass, 0.1, 2, 0.5, 0.2);
    dBodySetMass(state->flcarwheelbody, &wheelmass);
    dJointID joint = dJointCreateHinge(state->world, 0);
    dJointAttach(joint, state->carbodybody, state->flcarwheelbody);
    dJointSetHingeAnchor(joint, carX-1.5, carHeight - 0.5, carZ+2);
    dJointSetHingeAxis(joint, 1, 0, 0);
    dGeomID flcarwheelgeom = dCreateCylinder(state->worldSpace, 0.5, 0.2);
    dGeomSetBody(flcarwheelgeom, state->flcarwheelbody);

    dJointID motor = dJointCreateAMotor(state->world, 0);
    dJointAttach(motor, state->flcarwheelbody, state->carbodybody);
    dJointSetAMotorNumAxes(motor, 1);
    dJointSetAMotorAxis(motor, 0, 1, 1, 0, 0);
    dJointSetAMotorParam(motor, dParamVel, speed);
    dJointSetAMotorParam(motor, dParamFMax, force);

    state->frcarwheelbody = dBodyCreate(state->world);
    dBodySetPosition(state->frcarwheelbody, carX+1.5, carHeight - 0.5, carZ+2);
    dBodySetRotation(state->frcarwheelbody, m);
    dBodySetMass(state->frcarwheelbody, &wheelmass);
    joint = dJointCreateHinge(state->world, 0);
    dJointAttach(joint, state->carbodybody, state->frcarwheelbody);
    dJointSetHingeAnchor(joint, carX+1.5, carHeight - 0.5, carZ+2);
    dJointSetHingeAxis(joint, 1, 0, 0);
    dGeomID frcarwheelgeom = dCreateCylinder(state->worldSpace, 0.5, 0.2);
    dGeomSetBody(frcarwheelgeom, state->frcarwheelbody);

    motor = dJointCreateAMotor(state->world, 0);
    dJointAttach(motor, state->frcarwheelbody, state->carbodybody);
    dJointSetAMotorNumAxes(motor, 1);
    dJointSetAMotorAxis(motor, 0, 1, 1, 0, 0);
    dJointSetAMotorParam(motor, dParamVel, speed);
    dJointSetAMotorParam(motor, dParamFMax, force);

    state->blcarwheelbody = dBodyCreate(state->world);
    dBodySetPosition(state->blcarwheelbody, carX-1.5, carHeight - 0.5, carZ-2);
    dBodySetRotation(state->blcarwheelbody, m);
    dBodySetMass(state->blcarwheelbody, &wheelmass);
    joint = dJointCreateHinge(state->world, 0);
    dJointAttach(joint, state->carbodybody, state->blcarwheelbody);
    dJointSetHingeAnchor(joint, carX-1.5, carHeight - 0.5, carZ-2);
    dJointSetHingeAxis(joint, 1, 0, 0);
    dGeomID blcarwheelgeom = dCreateCylinder(state->worldSpace, 0.5, 0.2);
    dGeomSetBody(blcarwheelgeom, state->blcarwheelbody);

    motor = dJointCreateAMotor(state->world, 0);
    dJointAttach(motor, state->blcarwheelbody, state->carbodybody);
    dJointSetAMotorNumAxes(motor, 1);
    dJointSetAMotorAxis(motor, 0, 1, 1, 0, 0);
    dJointSetAMotorParam(motor, dParamVel, speed);
    dJointSetAMotorParam(motor, dParamFMax, force);

    state->brcarwheelbody = dBodyCreate(state->world);
    dBodySetPosition(state->brcarwheelbody, carX+1.5, carHeight - 0.5, carZ-2);
    dBodySetRotation(state->brcarwheelbody, m);
    dBodySetMass(state->brcarwheelbody, &wheelmass);
    joint = dJointCreateHinge(state->world, 0);
    dJointAttach(joint, state->carbodybody, state->brcarwheelbody);
    dJointSetHingeAnchor(joint, carX+1.5, carHeight - 0.5, carZ-2);
    dJointSetHingeAxis(joint, 1, 0, 0);
    dGeomID brcarwheelgeom = dCreateCylinder(state->worldSpace, 0.5, 0.2);
    dGeomSetBody(brcarwheelgeom, state->brcarwheelbody);

    motor = dJointCreateAMotor(state->world, 0);
    dJointAttach(motor, state->brcarwheelbody, state->carbodybody);
    dJointSetAMotorNumAxes(motor, 1);
    dJointSetAMotorAxis(motor, 0, 1, 1, 0, 0);
    dJointSetAMotorParam(motor, dParamVel, speed);
    dJointSetAMotorParam(motor, dParamFMax, force);

    state->var = new double[3];

    state->var = dBodyGetPosition(state->carbodybody);
//    cout << state->var[0] << " " << state->var[1] << " " << state->var[2] << endl;
    //TODO check if translation matrix from dBody can be used.

    dSpaceID cubespace = dHashSpaceCreate(state->worldSpace);

    for(int i = 0; i < NUM_CUBES/10; i++) {
        for(int k = 0; k < 10; k++) {
            state->cubebody[i*10+k] = dBodyCreate(state->world);
            dBodySetAutoDisableFlag(state->cubebody[i*10+k], 1);
            dBodySetPosition(state->cubebody[i*10+k], (i*2.01)-4, 0.9 + 2.01*k, -70);
            dGeomID cubegeom = dCreateBox(cubespace, 2, 2, 2);
            dGeomSetBody(cubegeom, state->cubebody[i*10+k]);
        }
    }

    {
        int indexSize = state->map->vertices.size()/3;
        unsigned int* index = new unsigned int[indexSize];
        for(int i = 0; i < indexSize; i++)
            index[i] = i;

        dTriMeshDataID triMeshData = dGeomTriMeshDataCreate();
        dGeomTriMeshDataBuildSingle(triMeshData, state->map->vertices.data(), 12, state->map->vertices.size()/3, index, indexSize, 12);
        dGeomID mapGeom = dCreateTriMesh(state->worldSpace, triMeshData, NULL, NULL, NULL);
        dGeomSetPosition(mapGeom, 0, 0, 0);
    }
//    state->monkeyBody = dBodyCreate(state->world);
//    {
//        int indexSize = state->monkey->vertices.size()/3;
//        unsigned int* index = new unsigned int[indexSize];
//        for(int i = 0; i < indexSize; i++)
//            index[i] = i;

//        dTriMeshDataID triMeshData = dGeomTriMeshDataCreate();
//        dGeomTriMeshDataBuildSingle(triMeshData, state->monkey->vertices.data(), 12, state->monkey->vertices.size()/3, index, indexSize, 12);
//        dGeomID monkeyGeom = dCreateTriMesh(state->worldSpace, triMeshData, NULL, NULL, NULL);
//        dGeomSetPosition(monkeyGeom, 0, 2, 0);
//        dGeomSetBody(monkeyGeom, state->monkeyBody);
//    }

    state->physicsContactgroup = dJointGroupCreate(0);

    return state;
}
示例#22
0
int main (int argc, char **argv)
{
  // setup pointers to drawstuff callback functions
  dsFunctions fn;
  fn.version = DS_VERSION;
  fn.start = &start;
  fn.step = &simLoop;
  fn.command = &command;
  fn.stop = 0;
  fn.path_to_textures = "../../drawstuff/textures";
  if(argc==2)
    {
        fn.path_to_textures = argv[1];
    }

  // create world
  dInitODE();
  world = dWorldCreate();

  space = dSimpleSpaceCreate(0);
  contactgroup = dJointGroupCreate (0);
  dWorldSetGravity (world,0,0,-0.5);
  dWorldSetCFM (world,1e-5);
  //dCreatePlane (space,0,0,1,0);
  memset (obj,0,sizeof(obj));
  
  Size[0] = 5.0f;
  Size[1] = 5.0f;
  Size[2] = 2.5f;
  
  Vertices[0][0] = -Size[0];
  Vertices[0][1] = -Size[1];
  Vertices[0][2] = Size[2];
  
  Vertices[1][0] = Size[0];
  Vertices[1][1] = -Size[1];
  Vertices[1][2] = Size[2];
  
  Vertices[2][0] = Size[0];
  Vertices[2][1] = Size[1];
  Vertices[2][2] = Size[2];
  
  Vertices[3][0] = -Size[0];
  Vertices[3][1] = Size[1];
  Vertices[3][2] = Size[2];
  
  Vertices[4][0] = 0;
  Vertices[4][1] = 0;
  Vertices[4][2] = 0;
  
  Indices[0] = 0;
  Indices[1] = 1;
  Indices[2] = 4;
  
  Indices[3] = 1;
  Indices[4] = 2;
  Indices[5] = 4;
  
  Indices[6] = 2;
  Indices[7] = 3;
  Indices[8] = 4;
  
  Indices[9] = 3;
  Indices[10] = 0;
  Indices[11] = 4;

  dTriMeshDataID Data = dGeomTriMeshDataCreate();

  dGeomTriMeshDataBuildSimple(Data, (dReal*)Vertices, VertexCount, Indices, IndexCount);
  
  TriMesh = dCreateTriMesh(space, Data, 0, 0, 0);

  //dGeomSetPosition(TriMesh, 0, 0, 1.0);
  
  Ray = dCreateRay(space, 0.9);
  dVector3 Origin, Direction;
  Origin[0] = 0.0;
  Origin[1] = 0;
  Origin[2] = 0.5;
  Origin[3] = 0;
  
  Direction[0] = 0;
  Direction[1] = 1.1f;
  Direction[2] = -1;
  Direction[3] = 0;
  dNormalize3(Direction);
  
  dGeomRaySet(Ray, Origin[0], Origin[1], Origin[2], Direction[0], Direction[1], Direction[2]);
  
  // run simulation
  dsSimulationLoop (argc,argv,352,288,&fn);

  dJointGroupDestroy (contactgroup);
  dSpaceDestroy (space);
  dWorldDestroy (world);
  dCloseODE();
  return 0;
}
示例#23
0
int main (int argc, char **argv)
{
  dMass m;
  dMatrix3 R;

  // setup pointers to drawstuff callback functions
  dsFunctions fn;
  fn.version = DS_VERSION;
  fn.start = &start;
  fn.step = &simLoop;
  fn.command = &command;
  fn.stop = 0;
  fn.path_to_textures = "../../drawstuff/textures";
  if(argc==2)
    fn.path_to_textures = argv[1];

  // create world
  world = dWorldCreate();
  space = dHashSpaceCreate (0);

  contactgroup = dJointGroupCreate (0);
  dWorldSetGravity (world,0,0,-9.8);
  dWorldSetQuickStepNumIterations (world, 64);

  // Create a static world using a triangle mesh that we can collide with.
  int numv = sizeof(world_vertices)/(3*sizeof(float));
  int numi = sizeof(world_indices)/ sizeof(int);
  printf("numv=%d, numi=%d\n", numv, numi);
  dTriMeshDataID Data = dGeomTriMeshDataCreate();

//  fprintf(stderr,"Building Single Precision Mesh\n");

  dGeomTriMeshDataBuildSingle
  (
    Data, 
    world_vertices, 
    3 * sizeof(float), 
    numv, 
    world_indices, 
    numi, 
    3 * sizeof(int)
  );

  world_mesh = dCreateTriMesh(space, Data, 0, 0, 0);
  dGeomTriMeshEnableTC(world_mesh, dSphereClass, false);
  dGeomTriMeshEnableTC(world_mesh, dBoxClass, false);
  dGeomSetPosition(world_mesh, 0, 0, 0.5);
  dRSetIdentity(R);
  //dIASSERT(dVALIDMAT3(R));

  dGeomSetRotation (world_mesh, R);

  float sx=0.0, sy=3.40, sz=6.80;
  sphbody = dBodyCreate (world);
  dMassSetSphere (&m,1,RADIUS);
  dBodySetMass (sphbody,&m);
  sphgeom = dCreateSphere(0, RADIUS);
  dGeomSetBody (sphgeom,sphbody);
  reset_ball();
  dSpaceAdd (space, sphgeom);

  // run simulation
  dsSimulationLoop (argc,argv,352,288,&fn);

  // Causes segm violation? Why?
  // (because dWorldDestroy() destroys body connected to geom; must call first!)
  dGeomDestroy(sphgeom);
  dGeomDestroy (world_mesh);

  dJointGroupEmpty (contactgroup);
  dJointGroupDestroy (contactgroup);
  dSpaceDestroy (space);
  dWorldDestroy (world);

  return 0;
}
static void command (int cmd)
{
  int i,j,k;
  dReal sides[3];
  dMass m;

  cmd = locase (cmd);
  if (cmd == 'b' || cmd == 's' || cmd == 'c' || cmd == 'x' || cmd == 'm' || cmd == 'y' ) {
    if (num < NUM) {
      i = num;
      num++;
    }
    else {
      i = nextobj;
      nextobj++;
      if (nextobj >= num) nextobj = 0;

      // destroy the body and geoms for slot i
      dBodyDestroy (obj[i].body);
      for (k=0; k < GPB; k++) {
	if (obj[i].geom[k]) dGeomDestroy (obj[i].geom[k]);
      }
      memset (&obj[i],0,sizeof(obj[i]));
    }

    obj[i].body = dBodyCreate (world);
    for (k=0; k<3; k++) sides[k] = dRandReal()*0.5+0.1;

    dMatrix3 R;
    if (random_pos) {
      dBodySetPosition (obj[i].body,
			dRandReal()*2-1,dRandReal()*2-1,dRandReal()+3);
      dRFromAxisAndAngle (R,dRandReal()*2.0-1.0,dRandReal()*2.0-1.0,
			  dRandReal()*2.0-1.0,dRandReal()*10.0-5.0);
    }
    else {
      dReal maxheight = 0;
      for (k=0; k<num; k++) {
	const dReal *pos = dBodyGetPosition (obj[k].body);
	if (pos[2] > maxheight) maxheight = pos[2];
      }
      dBodySetPosition (obj[i].body, 0,0,maxheight+1);
      dRFromAxisAndAngle (R,0,0,1,dRandReal()*10.0-5.0);
    }
    dBodySetRotation (obj[i].body,R);
    dBodySetData (obj[i].body,(void*)(size_t)i);

    if (cmd == 'b') {
      dMassSetBox (&m,DENSITY,sides[0],sides[1],sides[2]);
      obj[i].geom[0] = dCreateBox (space,sides[0],sides[1],sides[2]);
    }
    else if (cmd == 'c') {
      sides[0] *= 0.5;
      dMassSetCapsule (&m,DENSITY,3,sides[0],sides[1]);
      obj[i].geom[0] = dCreateCapsule (space,sides[0],sides[1]);
    }
    else if (cmd == 'y') {
      sides[1] *= 0.5;
      dMassSetCylinder (&m,DENSITY,3,sides[0],sides[1]);
      obj[i].geom[0] = dCreateCylinder (space,sides[0],sides[1]);
    }
	else if (cmd == 's') {
      sides[0] *= 0.5;
      dMassSetSphere (&m,DENSITY,sides[0]);
      obj[i].geom[0] = dCreateSphere (space,sides[0]);
    }
    else if (cmd == 'm') {
      dTriMeshDataID new_tmdata = dGeomTriMeshDataCreate();
      dGeomTriMeshDataBuildSingle(new_tmdata, &Vertices[0], 3 * sizeof(float), VertexCount, 
		  (dTriIndex*)&Indices[0], IndexCount, 3 * sizeof(dTriIndex));

      obj[i].geom[0] = dCreateTriMesh(space, new_tmdata, 0, 0, 0);

      // remember the mesh's dTriMeshDataID on its userdata for convenience.
      dGeomSetData(obj[i].geom[0], new_tmdata);

      dMassSetTrimesh( &m, DENSITY, obj[i].geom[0] );
      printf("mass at %f %f %f\n", m.c[0], m.c[1], m.c[2]);
      dGeomSetPosition(obj[i].geom[0], -m.c[0], -m.c[1], -m.c[2]);
      dMassTranslate(&m, -m.c[0], -m.c[1], -m.c[2]);
    }
    else if (cmd == 'x') {
      dGeomID g2[GPB];		// encapsulated geometries
      dReal dpos[GPB][3];	// delta-positions for encapsulated geometries

      // start accumulating masses for the encapsulated geometries
      dMass m2;
      dMassSetZero (&m);

      // set random delta positions
      for (j=0; j<GPB; j++) {
	for (k=0; k<3; k++) dpos[j][k] = dRandReal()*0.3-0.15;
      }

      for (k=0; k<GPB; k++) {
	obj[i].geom[k] = dCreateGeomTransform (space);
	dGeomTransformSetCleanup (obj[i].geom[k],1);
	if (k==0) {
	  dReal radius = dRandReal()*0.25+0.05;
	  g2[k] = dCreateSphere (0,radius);
	  dMassSetSphere (&m2,DENSITY,radius);
	}
	else if (k==1) {
	  g2[k] = dCreateBox (0,sides[0],sides[1],sides[2]);
	  dMassSetBox (&m2,DENSITY,sides[0],sides[1],sides[2]);
	}
	else {
	  dReal radius = dRandReal()*0.1+0.05;
	  dReal length = dRandReal()*1.0+0.1;
	  g2[k] = dCreateCapsule (0,radius,length);
	  dMassSetCapsule (&m2,DENSITY,3,radius,length);
	}
	dGeomTransformSetGeom (obj[i].geom[k],g2[k]);

	// set the transformation (adjust the mass too)
	dGeomSetPosition (g2[k],dpos[k][0],dpos[k][1],dpos[k][2]);
	dMassTranslate (&m2,dpos[k][0],dpos[k][1],dpos[k][2]);
	dMatrix3 Rtx;
	dRFromAxisAndAngle (Rtx,dRandReal()*2.0-1.0,dRandReal()*2.0-1.0,
			    dRandReal()*2.0-1.0,dRandReal()*10.0-5.0);
	dGeomSetRotation (g2[k],Rtx);
	dMassRotate (&m2,Rtx);

	// add to the total mass
	dMassAdd (&m,&m2);
      }

      // move all encapsulated objects so that the center of mass is (0,0,0)
      for (k=0; k<2; k++) {
	dGeomSetPosition (g2[k],
			  dpos[k][0]-m.c[0],
			  dpos[k][1]-m.c[1],
			  dpos[k][2]-m.c[2]);
      }
      dMassTranslate (&m,-m.c[0],-m.c[1],-m.c[2]);
    }

    for (k=0; k < GPB; k++) {
      if (obj[i].geom[k]) dGeomSetBody (obj[i].geom[k],obj[i].body);
    }

    dBodySetMass (obj[i].body,&m);
  }

  if (cmd == ' ') {
    selected++;
    if (selected >= num) selected = 0;
    if (selected < 0) selected = 0;
  }
  else if (cmd == 'd' && selected >= 0 && selected < num) {
    dBodyDisable (obj[selected].body);
  }
  else if (cmd == 'e' && selected >= 0 && selected < num) {
    dBodyEnable (obj[selected].body);
  }
  else if (cmd == 'a') {
    show_aabb ^= 1;
  }
  else if (cmd == 't') {
    show_contacts ^= 1;
  }
  else if (cmd == 'r') {
    random_pos ^= 1;
  }
}
示例#25
0
// Create a mesh shape object, add it to ODE's collision space, and initialize the mass member.
bool CMeshShape::Attach(dSpaceID SpaceID)
{
    if (!CShape::Attach(SpaceID)) FAIL;

	n_assert(!pVBuffer);
	n_assert(!pIBuffer);

	//!!!REVISIT IT! Now it's copypaste from A. Sysoev's code
	if (pInitMesh)
	{
		// load the vertices and indices
		VertexCount = pInitMesh->GetNumVertices();
		IndexCount  = 3 * pInitMesh->GetNumIndices() - 6;
		VertexWidth = pInitMesh->GetVertexWidth();

		// allocate vertex and index buffer
		int VBSize = pInitMesh->GetVertexBufferByteSize();
		int IBSize = IndexCount * sizeof(int);
		pVBuffer = (float*)n_malloc(VBSize);
		pIBuffer = (int*)n_malloc(IBSize);

		pInitMesh->SetUsage(nMesh2::ReadOnly);
		
		// read vertices and indices
		float *pVBuf = pInitMesh->LockVertices();
		memcpy(pVBuffer,pVBuf,VBSize);
		pInitMesh->UnlockVertices();
	    
		ushort *pIBuf = pInitMesh->LockIndices();

		// copy with conversion TriStrip -> TriList
		pIBuffer[0] = pIBuf[0];
		pIBuffer[1] = pIBuf[1];
		pIBuffer[2] = pIBuf[2];
		for(int i = 3, j = 2; i < pInitMesh->GetNumIndices(); i++)
		{
			pIBuffer[++j] = pIBuffer[j - 2];
			pIBuffer[++j] = pIBuffer[j - 2];
			pIBuffer[++j] = pIBuf[i];
		}
		pInitMesh->UnlockIndices();
	}
	else
	{
		n_assert(FileName.IsValid());

		if (FileName.CheckExtension("nvx2"))
		{
			nNvx2Loader MeshLoader;
			if (!LoadFromFile(MeshLoader)) FAIL;
		}
		else if (FileName.CheckExtension("n3d2"))
		{
			nN3d2Loader MeshLoader;
			if (!LoadFromFile(MeshLoader)) FAIL;
		}
		else
		{
			n_error("CMeshShape: invalid file extension in '%Sphere'", FileName.Get());
			FAIL;
		}
    }

	// fix my collide bits, we don't need to collide against other static and disabled entities
	SetCategoryBits(Static);
	SetCollideBits(Dynamic);

	// create an ODE TriMeshData object from the loaded vertices and indices
	ODETriMeshDataID = dGeomTriMeshDataCreate();

	//!!!CHECK IT!
	// index buffer оказывается должен быть всегда типа int[]
	// хм, эта функция похоже никак не реагирует на передаваемый TriStride,
	// пришлось конвертировать TriStrip в TriList
	dGeomTriMeshDataBuildSingle(ODETriMeshDataID,
								pVBuffer,
								VertexWidth * sizeof(float),
								VertexCount,
								pIBuffer,
								IndexCount,
								3 * sizeof(int));

	ODETriMeshID = dCreateTriMesh(0, ODETriMeshDataID, 0, 0, 0);
	AttachGeom(ODETriMeshID, SpaceID);

	//!!!!!!!FIXME: apply shape mass here!

	OK;
}