Пример #1
0
// -----------------------------------------------------------------------
void MyCloth::generateMuscleMeshDesc(NxClothMeshDesc &desc, float height, float radius, int heightDivs, int aroundDivs)
{
	desc.numVertices				= aroundDivs*(heightDivs+1);
	desc.numTriangles				= aroundDivs*heightDivs*2;
	desc.pointStrideBytes			= sizeof(NxVec3);
	desc.triangleStrideBytes		= 3*sizeof(NxU32);
	desc.vertexMassStrideBytes		= sizeof(NxReal);
	desc.vertexFlagStrideBytes		= sizeof(NxU32);
	desc.points						= (NxVec3*)malloc(sizeof(NxVec3)*desc.numVertices);
	desc.triangles					= (NxU32*)malloc(sizeof(NxU32)*desc.numTriangles*3);
	desc.vertexMasses				= 0;
	desc.vertexFlags				= 0;
	desc.flags						= 0;
	desc.flags						= NX_CLOTH_MESH_WELD_VERTICES;
	desc.weldingDistance			= 0.0001f;

	mMaxVertices = desc.numVertices;
	mMaxIndices  = 3 * desc.numTriangles;

	//points
	NxVec3* p = (NxVec3*)desc.points;
	for(int h=0; h<=heightDivs; h++) {
		for(int i=0; i<aroundDivs; i++) {
			double hDelta=((double)h)/heightDivs;
			double theta=((double)i)/aroundDivs*2.0*PI;
			double r=sin(hDelta*PI)*radius; //find radius of muscle, use sin func for now
			double x=r*cos(theta);
			double y=height*hDelta;
			double z=r*sin(theta);
			p->set((float)x,(float)y,(float)z);
			p++;
		}
	}


	//indices
	NxU32 *ind = (NxU32*)desc.triangles;
	for(int h=0; h<heightDivs; h++) {
		for(int i=0; i<aroundDivs; i++) {
			NxU32 i0 = h*aroundDivs + i;
			NxU32 i1 = h*aroundDivs + ((i+1)%aroundDivs); //wrap around
			NxU32 i2 = (h+1)*aroundDivs + i;
			NxU32 i3 = (h+1)*aroundDivs + ((i+1)%aroundDivs); //wrap around
			*ind++ = i0; *ind++ = i2; *ind++ = i1;
			
			*ind++ = i1; *ind++ = i2; *ind++ = i3;
		}
	}


	//texcoords
	mNumTempTexCoords = 0;
	mTempTexCoords = NULL;
}
Пример #2
0
void ViewUnProject(int xi, int yi, float depth, NxVec3 &v)
{
//We cannot do picking easily on the xbox/PS3 anyway
#if defined(_XBOX)||defined(__CELLOS_LV2__)
	v=NxVec3(0,0,0);
#else
	GLint viewPort[4];
	GLdouble modelMatrix[16];
	GLdouble projMatrix[16];
	glGetIntegerv(GL_VIEWPORT, viewPort);
	glGetDoublev(GL_MODELVIEW_MATRIX, modelMatrix);
	glGetDoublev(GL_PROJECTION_MATRIX, projMatrix);
	yi = viewPort[3] - yi - 1;
	GLdouble wx, wy, wz;
	gluUnProject((GLdouble) xi, (GLdouble) yi, (GLdouble) depth,
	modelMatrix, projMatrix, viewPort, &wx, &wy, &wz);
	v.set((NxReal)wx, (NxReal)wy, (NxReal)wz);
#endif
}
Пример #3
0
void Cloth::generateRegularMeshDesc(NxClothMeshDesc &desc, NxReal w, NxReal h, NxReal d, bool 
									texCoords)
{
	int numX = (int)(w / d) + 1;
	int numY = (int)(h / d) + 1;

	desc.numVertices				= (numX+1) * (numY+1);
	desc.numTriangles				= numX*numY*2;
	desc.pointStrideBytes			= sizeof(NxVec3);
	desc.triangleStrideBytes		= 3*sizeof(NxU32);
	desc.vertexMassStrideBytes		= sizeof(NxReal);
	desc.vertexFlagStrideBytes		= sizeof(NxU32);
	desc.points						= (NxVec3*)malloc(sizeof(NxVec3)*desc.numVertices);
	desc.triangles					= (NxU32*)malloc(sizeof(NxU32)*desc.numTriangles*3);
	desc.vertexMasses				= 0;
	desc.vertexFlags				= 0;
	desc.flags						= 0;

	mMaxVertices = TEAR_MEMORY_FACTOR * desc.numVertices;
	mMaxIndices  = 3 * desc.numTriangles;


	_geo_cloth = new osg::Geode;
	int i,j;
	// create particles - POINTS
	{
		osg::Geometry* pointsGeom = new osg::Geometry();
		osg::Vec3Array* vertices = new osg::Vec3Array;		

		NxVec3 *p = (NxVec3*)desc.points;
		for (i = 0; i <= numY; i++) {
			for (j = 0; j <= numX; j++) {
				p->set(d*j, 0.0f, d*i); 
				vertices->push_back(osg::Vec3f(d*j, d*i, 0.0f));
				p++;
			}
		}

		pointsGeom->setVertexArray(vertices);

		osg::Vec4Array* colors = new osg::Vec4Array;
		colors->push_back(osg::Vec4(1.0f,1.0f,0.0f,0.8f));

		pointsGeom->setColorArray(colors);
		pointsGeom->setColorBinding(osg::Geometry::BIND_OVERALL);


		// set the normal in the same way color.
		osg::Vec3Array* normals = new osg::Vec3Array;
		normals->push_back(osg::Vec3(0.0f,-1.0f,0.0f));
		pointsGeom->setNormalArray(normals);
		pointsGeom->setNormalBinding(osg::Geometry::BIND_OVERALL);
		
		osg::StateSet* stateSet = new osg::StateSet();
        
		pointsGeom->setStateSet(stateSet);
		pointsGeom->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::POINTS,0,vertices->size()));
		

		osg::Point* point = new osg::Point;
        point->setDistanceAttenuation(osg::Vec3(0.0,0.0000,0.05f));
		point->setSize(20.0f);
        stateSet->setAttribute(point);

		osg::PointSprite *sprite = new osg::PointSprite();
        stateSet->setTextureAttributeAndModes(0, sprite, osg::StateAttribute::ON);

		

		// add the points geometry to the geode.
		_geo_cloth->addDrawable(pointsGeom);
	}

	
	if (texCoords) {
		mTempTexCoords = (float *)malloc(sizeof(float)*2*TEAR_MEMORY_FACTOR*desc.numVertices);
		float *f = mTempTexCoords;
		float dx = 1.0f; if (numX > 0) dx /= numX;
		float dy = 1.0f; if (numY > 0) dy /= numY;
		for (i = 0; i <= numY; i++) {
			for (j = 0; j <= numX; j++) {
				*f++ = j*dx;
				*f++ = i*dy;
			}
		}
		
	
		mNumTempTexCoords = desc.numVertices;
	}
	else
	{
		mNumTempTexCoords = 0;
		mTempTexCoords = NULL;
	}

	NxU32 *id = (NxU32*)desc.triangles;
	for (i = 0; i < numY; i++) {
		for (j = 0; j < numX; j++) {
			NxU32 i0 = i * (numX+1) + j;
			NxU32 i1 = i0 + 1;
			NxU32 i2 = i0 + (numX+1);
			NxU32 i3 = i2 + 1;
			if ((j+i)%2) {
				*id++ = i0; *id++ = i2; *id++ = i1;
				*id++ = i1; *id++ = i2; *id++ = i3;
			}
			else {
				*id++ = i0; *id++ = i2; *id++ = i3;
				*id++ = i0; *id++ = i3; *id++ = i1;
			}
		}
	}

}
Пример #4
0
// -----------------------------------------------------------------------
void MyCloth::generateRegularMeshDesc(NxClothMeshDesc &desc, NxReal w, NxReal h, NxReal d, bool texCoords)
{
	int numX = (int)(w / d) + 1;
	int numY = (int)(h / d) + 1;

	desc.numVertices				= (numX+1) * (numY+1);
	desc.numTriangles				= numX*numY*2;
	desc.pointStrideBytes			= sizeof(NxVec3);
	desc.triangleStrideBytes		= 3*sizeof(NxU32);
	desc.vertexMassStrideBytes		= sizeof(NxReal);
	desc.vertexFlagStrideBytes		= sizeof(NxU32);
	desc.points						= (NxVec3*)malloc(sizeof(NxVec3)*desc.numVertices);
	desc.triangles					= (NxU32*)malloc(sizeof(NxU32)*desc.numTriangles*3);
	desc.vertexMasses				= 0;
	desc.vertexFlags				= 0;
	desc.flags						= 0;

	mMaxVertices = desc.numVertices;
	mMaxIndices  = 3 * desc.numTriangles;

	int i,j;
	NxVec3 *p = (NxVec3*)desc.points;
	for (i = 0; i <= numY; i++) {
		for (j = 0; j <= numX; j++) {
			p->set(d*j, 0.0f, d*i); 
			p++;
		}
	}

	if (texCoords) {
		mTempTexCoords = (GLfloat *)malloc(sizeof(GLfloat)*2*desc.numVertices);
		GLfloat *f = mTempTexCoords;
		GLfloat dx = 1.0f; if (numX > 0) dx /= numX;
		GLfloat dy = 1.0f; if (numY > 0) dy /= numY;
		for (i = 0; i <= numY; i++) {
			for (j = 0; j <= numX; j++) {
				*f++ = j*dx;
				*f++ = i*dy;
			}
		}
		mNumTempTexCoords = desc.numVertices;
	}
	else
	{
		mNumTempTexCoords = 0;
		mTempTexCoords = NULL;
	}

	NxU32 *id = (NxU32*)desc.triangles;
	for (i = 0; i < numY; i++) {
		for (j = 0; j < numX; j++) {
			NxU32 i0 = i * (numX+1) + j;
			NxU32 i1 = i0 + 1;
			NxU32 i2 = i0 + (numX+1);
			NxU32 i3 = i2 + 1;
			if ((j+i)%2) {
				*id++ = i0; *id++ = i2; *id++ = i1;
				*id++ = i1; *id++ = i2; *id++ = i3;
			}
			else {
				*id++ = i0; *id++ = i2; *id++ = i3;
				*id++ = i0; *id++ = i3; *id++ = i1;
			}
		}
	}

}
Пример #5
0
void PxCloth::_initClothMesh()
{
   // Make sure we can change the world.
   mWorld->releaseWriteLock();

   _releaseMesh();

   // Must have at least 2 verts.
   mPatchVerts.x = getMax( 2, mPatchVerts.x );
   mPatchVerts.y = getMax( 2, mPatchVerts.y );

   // Generate a uniform cloth patch, 
   // w and h are the width and height, 
   // d is the distance between vertices.  
   mNumVertices = mPatchVerts.x * mPatchVerts.y;
   mNumIndices = (mPatchVerts.x-1) * (mPatchVerts.y-1) * 2;

   NxClothMeshDesc desc;
   desc.numVertices = mNumVertices;    
   desc.numTriangles = mNumIndices;   
   desc.pointStrideBytes = sizeof(NxVec3);    
   desc.triangleStrideBytes = 3*sizeof(NxU32);    
   desc.points = (NxVec3*)dMalloc(sizeof(NxVec3)*desc.numVertices);    
   desc.triangles = (NxU32*)dMalloc(sizeof(NxU32)*desc.numTriangles*3);    
   desc.flags = 0;    

   U32 i,j;    
   NxVec3 *p = (NxVec3*)desc.points;    
   
   F32 patchWidth = mPatchSize.x / (F32)( mPatchVerts.x - 1 );
   F32 patchHeight = mPatchSize.y / (F32)( mPatchVerts.y - 1 );

   for (i = 0; i < mPatchVerts.y; i++) 
   {        
      for (j = 0; j < mPatchVerts.x; j++) 
      {            
         p->set( patchWidth * j, 0.0f, patchHeight * i );     
         p++;
      }    
   }

   NxU32 *id = (NxU32*)desc.triangles;    
   
   for (i = 0; i < mPatchVerts.y-1; i++) 
   {        
      for (j = 0; j < mPatchVerts.x-1; j++) 
      {            
         NxU32 i0 = i * mPatchVerts.x + j;            
         NxU32 i1 = i0 + 1;            
         NxU32 i2 = i0 + mPatchVerts.x;            
         NxU32 i3 = i2 + 1;            
         if ( (j+i) % 2 ) 
         {                
            *id++ = i0; 
            *id++ = i2; 
            *id++ = i1;                
            *id++ = i1; 
            *id++ = i2; 
            *id++ = i3;            
         }            
         else 
         {                
            *id++ = i0; 
            *id++ = i2; 
            *id++ = i3;                
            *id++ = i0; 
            *id++ = i3; 
            *id++ = i1;            
         }        
      }    
   }   
   
   NxCookingInterface *cooker = PxWorld::getCooking();
   cooker->NxInitCooking();

   // Ok... cook the mesh!
   NxCookingParams params;
   params.targetPlatform = PLATFORM_PC;
   params.skinWidth = 0.01f;
   params.hintCollisionSpeed = false;

   cooker->NxSetCookingParams( params );
  
   PxMemStream cooked;	
  
   if ( cooker->NxCookClothMesh( desc, cooked ) )
   {
      cooked.resetPosition();
      mClothMesh = gPhysicsSDK->createClothMesh( cooked );
   }
   
   cooker->NxCloseCooking();
   
   NxVec3 *ppoints = (NxVec3*)desc.points;
   NxU32 *triangs = (NxU32*)desc.triangles;

   dFree( ppoints );
   dFree( triangs );

   if ( mClothMesh )
      _initReceiveBuffers();
}
Пример #6
0
int main(int argc, char **argv)
{
    //init and PVD
    bool initialized = false;
    NxPhysicsSDK *physicsSDK = NxCreatePhysicsSDK(NX_PHYSICS_SDK_VERSION);
    if (!physicsSDK)
        return 0;
    else
        physicsSDK->getFoundationSDK().getRemoteDebugger()->connect("localhost", 5425);
    physicsSDK->setParameter(NX_CONTINUOUS_CD, true);

    initialized = true;

    //create a scene
    bool sceneInit = false;
    NxSceneDesc sceneDesc;
    sceneDesc.gravity.set(0, -9.81f, 0);
    gScene = physicsSDK->createScene(sceneDesc);

    if (gScene != NULL)
        sceneInit = true;

    //create a plane
    {
        NxActorDesc actorDesc;
        NxPlaneShapeDesc planeDesc;
        //planeDesc.normal = NxVec3(0, 0, 1);
        //planeDesc.d = -10.0f;

        actorDesc.shapes.pushBack(&planeDesc);
        gScene->createActor(actorDesc);
    }

    //create material
    NxMaterial *defaultMaterial = gScene->getMaterialFromIndex(0);
    defaultMaterial->setRestitution(0.3f);
    defaultMaterial->setStaticFriction(0.5f);
    defaultMaterial->setDynamicFriction(0.5f);



    //create a box
    {
        NxActorDesc actorDesc;
        NxBodyDesc bodyDesc;
        bodyDesc.angularDamping = 0.5;
        bodyDesc.linearVelocity = NxVec3(1, 0, 0);
        actorDesc.body = &bodyDesc;

        NxBoxShapeDesc boxDesc;
        boxDesc.dimensions = NxVec3(2.0f, 3.0f, 4.0f);
        actorDesc.shapes.pushBack(&boxDesc);
        actorDesc.density = 10.0f;
        actorDesc.globalPose.t = NxVec3(10.0f, 10.0f, 10.0f);
        gScene->createActor(actorDesc)->userData = NULL;
    }

    //create a cloth
    {
        // Create the objects in the scene
        NxActor* sphere1 = CreateSphere(NxVec3(-1, 0, -0.5), 1, 10);
        NxActor* box1 = CreateBox(NxVec3(1, 0, -1), NxVec3(1, 1, 1), 10);
        NxActor* box2 = CreateBox(NxVec3(0, 6.5, 0), NxVec3(5, 0.5, 0.5), 10);
        NxActor* box3 = CreateBox(NxVec3(0, 6.5, -7), NxVec3(5, 0.5, 0.5), 10);

        box2->setLinearDamping(5);
        box3->setLinearDamping(5);
        NxD6JointDesc d6Desc;
        d6Desc.actor[0] = NULL;
        d6Desc.actor[1] = box2;
        NxVec3 globalAnchor(0, 7, 0);
        d6Desc.localAnchor[0] = globalAnchor;
        box2->getGlobalPose().multiplyByInverseRT(globalAnchor, d6Desc.localAnchor[1]);
        box2->raiseBodyFlag(NX_BF_DISABLE_GRAVITY);

        box3->getGlobalPose().multiplyByInverseRT(globalAnchor, d6Desc.localAnchor[1]);
        box3->raiseBodyFlag(NX_BF_DISABLE_GRAVITY);

        d6Desc.localAxis[0] = NxVec3(1, 0, 0);
        d6Desc.localNormal[0] = NxVec3(0, 1, 0);
        d6Desc.localAxis[1] = NxVec3(1, 0, 0);
        d6Desc.localNormal[1] = NxVec3(0, 1, 0);

        d6Desc.twistMotion = NX_D6JOINT_MOTION_LOCKED;
        d6Desc.swing1Motion = NX_D6JOINT_MOTION_LOCKED;
        d6Desc.swing2Motion = NX_D6JOINT_MOTION_LOCKED;
        d6Desc.xMotion = NX_D6JOINT_MOTION_FREE;
        d6Desc.yMotion = NX_D6JOINT_MOTION_FREE;
        d6Desc.zMotion = NX_D6JOINT_MOTION_FREE;

        NxJoint* d6Joint = gScene->createJoint(d6Desc);

        NxClothDesc clothDesc;
        clothDesc.globalPose.t = NxVec3(4, 7, 0);
        clothDesc.thickness = 0.2;
        //clothDesc.density = 1;
        clothDesc.bendingStiffness = 0.5;
        clothDesc.stretchingStiffness = 1;
        //clothDesc.dampingCoefficient = 0.5;
        clothDesc.friction = 0.5;
        //clothDesc.collisionResponseCoefficient = 1;
        //clothDesc.attachmentResponseCoefficient = 1;
        //clothDesc.solverIterations = 5;
        //clothDesc.flags |= NX_CLF_STATIC;
        //clothDesc.flags |= NX_CLF_DISABLE_COLLISION;
        //clothDesc.flags |= NX_CLF_VISUALIZATION;
        //clothDesc.flags |= NX_CLF_GRAVITY;
        clothDesc.flags |= NX_CLF_BENDING;
        //clothDesc.flags |= NX_CLF_BENDING_ORTHO;
        clothDesc.flags |= NX_CLF_DAMPING;
        //clothDesc.flags |= NX_CLF_COMDAMPING;
        clothDesc.flags |= NX_CLF_COLLISION_TWOWAY;

        clothDesc.flags &= ~NX_CLF_HARDWARE;
        clothDesc.flags |= NX_CLF_FLUID_COLLISION;
        clothDesc.selfCollisionThickness = 10.0f;


        NxReal w = 8;
        NxReal h = 7;
        NxReal d = 0.05;
        NxClothMeshDesc meshDesc;
        bool mInitDone = false;

        int numX = (int)(w / d) + 1;
        int numY = (int)(h / d) + 1;


        meshDesc.numVertices = (numX + 1) * (numY + 1);
        meshDesc.numTriangles = numX*numY * 2;
        meshDesc.pointStrideBytes = sizeof(NxVec3);
        meshDesc.triangleStrideBytes = 3 * sizeof(NxU32);
        meshDesc.vertexMassStrideBytes = sizeof(NxReal);
        meshDesc.vertexFlagStrideBytes = sizeof(NxU32);
        meshDesc.points = (NxVec3*)malloc(sizeof(NxVec3)*meshDesc.numVertices);
        meshDesc.triangles = (NxU32*)malloc(sizeof(NxU32)*meshDesc.numTriangles * 3);
        meshDesc.vertexMasses = 0;
        meshDesc.vertexFlags = 0;
        meshDesc.flags = 0;

        int i, j;
        NxVec3 *p = (NxVec3*)meshDesc.points;
        for (i = 0; i <= numY; i++) {
            for (j = 0; j <= numX; j++) {
                p->set(-d*j, 0.0f, -d*i);
                p++;
            }
        }

        NxU32 *id = (NxU32*)meshDesc.triangles;
        for (i = 0; i < numY; i++) {
            for (j = 0; j < numX; j++) {
                NxU32 i0 = i * (numX + 1) + j;
                NxU32 i1 = i0 + 1;
                NxU32 i2 = i0 + (numX + 1);
                NxU32 i3 = i2 + 1;
                if ((j + i) % 2) {
                    *id++ = i0;
                    *id++ = i2;
                    *id++ = i1;
                    *id++ = i1;
                    *id++ = i2;
                    *id++ = i3;
                }
                else {
                    *id++ = i0;
                    *id++ = i2;
                    *id++ = i3;
                    *id++ = i0;
                    *id++ = i3;
                    *id++ = i1;
                }
            }
        }
        // if we want tearing we must tell the cooker
        // this way it will generate some space for particles that will be generated during tearing
        if (meshDesc.flags & NX_CLF_TEARABLE)
            meshDesc.flags |= NX_CLOTH_MESH_TEARABLE;


        //cooking
        static NxCookingInterface *gCooking = 0;
        gCooking = NxGetCookingLib(NX_PHYSICS_SDK_VERSION);
        gCooking->NxInitCooking();

        gCooking->NxCookClothMesh(meshDesc, UserStream("e:\\cooked.bin", false));

        //Meshdata Buffers
        NxMeshData mReceiveBuffers;
        // here we setup the buffers through which the SDK returns the dynamic cloth data
        // we reserve more memory for vertices than the initial mesh takes
        // because tearing creates new vertices
        // the SDK only tears cloth as long as there is room in these buffers
        NxU32 numVertices = meshDesc.numVertices;
        NxU32 numTriangles = meshDesc.numTriangles;

        NxU32 maxVertices = 2 * numVertices;
        mReceiveBuffers.verticesPosBegin = (NxVec3*)malloc(sizeof(NxVec3)*maxVertices);
        mReceiveBuffers.verticesNormalBegin = (NxVec3*)malloc(sizeof(NxVec3)*maxVertices);
        mReceiveBuffers.verticesPosByteStride = sizeof(NxVec3);
        mReceiveBuffers.verticesNormalByteStride = sizeof(NxVec3);
        mReceiveBuffers.maxVertices = maxVertices;
        mReceiveBuffers.numVerticesPtr = (NxU32*)malloc(sizeof(NxU32));

        // the number of triangles is constant, even if the cloth is torn
        NxU32 maxIndices = 3 * numTriangles;
        mReceiveBuffers.indicesBegin = (NxU32*)malloc(sizeof(NxU32)*maxIndices);
        mReceiveBuffers.indicesByteStride = sizeof(NxU32);
        mReceiveBuffers.maxIndices = maxIndices;
        mReceiveBuffers.numIndicesPtr = (NxU32*)malloc(sizeof(NxU32));

        // the parent index information would be needed if we used textured cloth
        NxU32 maxParentIndices = maxVertices;
        mReceiveBuffers.parentIndicesBegin = (NxU32*)malloc(sizeof(NxU32)*maxParentIndices);
        mReceiveBuffers.parentIndicesByteStride = sizeof(NxU32);
        mReceiveBuffers.maxParentIndices = maxParentIndices;
        mReceiveBuffers.numParentIndicesPtr = (NxU32*)malloc(sizeof(NxU32));

        // init the buffers in case we want to draw the mesh
        // before the SDK as filled in the correct values
        *mReceiveBuffers.numVerticesPtr = 0;
        *mReceiveBuffers.numIndicesPtr = 0;



        clothDesc.clothMesh = physicsSDK->createClothMesh(UserStream("e:\\cooked.bin", true));
        clothDesc.meshData = mReceiveBuffers;

        NxCloth *mCloth;
        mCloth = gScene->createCloth(clothDesc);
        mCloth->attachToShape(*box2->getShapes(), NX_CLOTH_ATTACHMENT_TWOWAY);
        mCloth->attachToShape(*box3->getShapes(), NX_CLOTH_ATTACHMENT_TWOWAY);
    }

    //create fluid 1
    {
        //fluid = CreateFluid(NxVec3(0, 12, -3.5), 15, 0.1, gScene);
    }
    //create fluid 2
    {
        //Create a set of initial particles
        ParticleSDK*	initParticles = new ParticleSDK[max_particles];
        unsigned initParticlesNum = 0;

        //Create particle filled sphere in buffer.
        NxVec3 fluidPos(0, 2, 0);
        NxVec3 offsetPos(0, 12, -3.5);
        float distance = 0.1f;
        //#ifdef __PPCGEKKO__
        //	unsigned sideNum = 12;
        //#else
        unsigned sideNum = 16;
        //#endif

        //Setup structure to pass initial particles.
        NxParticleData initParticleData;
        initParticlesNum = 0;
        initParticleData.numParticlesPtr = &initParticlesNum;
        initParticleData.bufferPos = &initParticles[0].position.x;
        initParticleData.bufferPosByteStride = sizeof(ParticleSDK);
        initParticleData.bufferVel = &initParticles[0].velocity.x;
        initParticleData.bufferVelByteStride = sizeof(ParticleSDK);

        CreateParticleSphere(initParticleData, max_particles, false, offsetPos, NxVec3(0, 0, 0), 0.0f, distance, sideNum);

        //Setup fluid descriptor
        NxFluidDesc fluidDesc;
        fluidDesc.maxParticles = max_particles;
        fluidDesc.kernelRadiusMultiplier = 2.0f;
        fluidDesc.restParticlesPerMeter = 10.0f;
        fluidDesc.motionLimitMultiplier = 3.0f;
        fluidDesc.packetSizeMultiplier = 8;
        fluidDesc.collisionDistanceMultiplier = 0.1;
        fluidDesc.stiffness = 50.0f;
        fluidDesc.viscosity = 40.0f;
        fluidDesc.restDensity = 1000.0f;
        fluidDesc.damping = 0.0f;
        fluidDesc.restitutionForStaticShapes = 0.0f;
        fluidDesc.dynamicFrictionForStaticShapes = 0.05f;
        fluidDesc.simulationMethod = NX_F_SPH;
        fluidDesc.flags &= ~NX_FF_HARDWARE;

        //Add initial particles to fluid creation.
        fluidDesc.initialParticleData = initParticleData;

        //Create user fluid.
        //- create NxFluid in NxScene
        //- setup the buffers to read from data from the SDK
        //- set NxFluid::userData field to MyFluid instance
        bool trackUserData = false;
        bool provideCollisionNormals = false;
        MyFluid* fluid = new MyFluid(gScene, fluidDesc, trackUserData, provideCollisionNormals, NxVec3(0.4f, 0.5f, 0.9f), 0.03f);
        assert(fluid);
        gMyFluids.pushBack(fluid);
    }
    //simulate
    for (int i = 0; i < 3000; i++)
    {
        gScene->simulate(1.0f / 60.f);
        gScene->flushStream();
        //GetPhysicsResults
        gScene->fetchResults(NX_RIGID_BODY_FINISHED, true);

        // update fluid status
        if (i == 400)
        {
            MyFluid* fluid = gMyFluids[0];
            const ParticleSDK* particles = fluid->getParticles();
            unsigned particlesNum = fluid->getParticlesNum();
            if (!gUpdates)
            {
                gUpdates = new ParticleUpdateSDK[max_particles];
            }
            for (unsigned i = 0; i < particlesNum; i++)
            {
                ParticleUpdateSDK& update = gUpdates[i];
                NxVec3& force = update.force;
                force.set(0, 0, 0);
                NxU32& flags = update.flags;
                if (i >= particlesNum/2)
                {
                    flags = 0;
                    flags |= NX_FP_DELETE;
                }
                else
                {
                    flags = 0;
                }

            }
            //在这里更改粒子的属性
            NxParticleUpdateData updateData;
            updateData.bufferFlag = &gUpdates[0].flags;
            updateData.bufferFlagByteStride = sizeof(ParticleUpdateSDK);
            fluid->getNxFluid()->updateParticles(updateData);
        }
    }


    //release
    if (physicsSDK != NULL)
    {
        if (gScene != NULL)
            physicsSDK->releaseScene(*gScene);
        gScene = NULL;
        NxReleasePhysicsSDK(physicsSDK);
        physicsSDK = NULL;
    }
    return 1;
}
Пример #7
0
static void calculateIntersectionDetails(NxBox& oob1, NxBox& oob2, float& outVolume2, NxVec3& outGlobalIntersectionCenter2)
{
    float step = 0.5f;
    if( step > oob2.extents.x * 2 ) step = oob2.extents.x * 2;
    if( step > oob2.extents.y * 2 ) step = oob2.extents.y * 2;
    if( step > oob2.extents.z * 2 ) step = oob2.extents.z * 2;

    float x = -oob2.extents.x;
    float y = -oob2.extents.y;
    float z = -oob2.extents.z;

    NxVec3 localPoint;
    NxVec3 globalPoint;
    NxVec3 localIntersectionCenter( 0,0,0 );
    unsigned int numTotalPoints = 0;
    unsigned int numIntersectedPoints = 0;

    NxMat34 matrix2;
    matrix2.M = oob2.rot;
    matrix2.t = oob2.center;

    while( x <= oob2.extents.x )
    {
        while( y <= oob2.extents.y )
        {
            while( z <= oob2.extents.z )
            {
                localPoint.set( x,y,z );
                globalPoint = matrix2 * localPoint;
				
                if( NxBoxContainsPoint( oob1, globalPoint ) )
                {
                    if( numIntersectedPoints )
                    {
                        localIntersectionCenter = localPoint;
                    }
                    else
                    {
                        localIntersectionCenter += localPoint;
                    }
                    numIntersectedPoints++;
                }
                numTotalPoints++;
                z += step;
            }
            z = -oob2.extents.z;
            y += step;
        }
        y = -oob2.extents.y;
        x += step;
    }

    outVolume2 = float( numIntersectedPoints ) / float( numTotalPoints );
        
    if( numIntersectedPoints )
    {
        localIntersectionCenter = localIntersectionCenter / float( numIntersectedPoints );
    }   
    outGlobalIntersectionCenter2 = matrix2 * localIntersectionCenter;

    // getCore()->logMessage( "oobb intersection volume: %3.2f (%d/%d) step: %3.2f", outVolume2, numIntersectedPoints, numTotalPoints, step );
}
void SampleCollision::setup()
{

	SetTitleString(getName());
#ifdef __PPCGEKKO__
	SetHelpString("    a: create rigid bodies");
#else	
	SetHelpString("    b: create rigid bodies");
#endif	

	gShadows = false;

	// Create objects in the scene

	if (!InitCooking(gAllocator, &gErrorStream)) 
	{
		printf("\nError: Unable to initialize the cooking library, exiting the sample.\n\n");
		return;
	}

	// Load ASE file
	CookASE("fluidSample.ase", gScene, NxVec3(1,10,0));
	CookASE("coolFlow.ase", gScene, NxVec3(1,6,-0), NxVec3(1,0.2,1));
	CloseCooking();

	// Add a box shaped drain.
	NxActorDesc boxDrainActor;
	NxBoxShapeDesc boxDrainShape;
	boxDrainActor.shapes.pushBack(&boxDrainShape);
	boxDrainShape.dimensions.set(40,1,40);
	boxDrainShape.shapeFlags |= NX_SF_FLUID_DRAIN;
	boxDrainActor.globalPose.t.set(0, 0, 0);
	gScene->createActor(boxDrainActor);

	//Pre cook hotspots
	NxBounds3 precookAABB;
	precookAABB.set(NxVec3(-20,-20,-20), NxVec3(20,20,20));
//	gScene->cookFluidMeshHotspot(precookAABB, PACKET_SIZE_MULTIPLIER, REST_PARTICLES_PER_METER, KERNEL_RADIUS_MULTIPLIER, MOTION_LIMIT_MULTIPLIER, COLLISION_DISTANCE_MULTIPLIER );


	//Create a set of initial particles
	ParticleSDK*	initParticles = new ParticleSDK[MAX_PARTICLES];
	unsigned initParticlesNum = 0;

	NxVec3 fluidPos(0, 11.6, 0);
	float distance = 0.1f;
	unsigned sideNum = 16;	
	float rad = sideNum*distance*0.5f;
	for (unsigned i=0; i<sideNum; i++)
		for (unsigned j=0; j<sideNum; j++)
			for (unsigned k=0; k<sideNum; k++)
			{
				NxVec3 p = NxVec3(i*distance,j*distance,k*distance);
				if (p.distance(NxVec3(rad,rad,rad)) < rad)
				{
					p += fluidPos;
					ParticleSDK& newParticle = initParticles[initParticlesNum++];
					newParticle.position = p;
					newParticle.velocity = NxVec3(0,0,0);
				}
			}
	//Setup structure to pass initial particles.
	NxParticleData initParticleData;
	initParticleData.numParticlesPtr		= &initParticlesNum;
	initParticleData.bufferPos				= &initParticles[0].position.x;
	initParticleData.bufferPosByteStride	= sizeof(ParticleSDK);
	initParticleData.bufferVel				= &initParticles[0].velocity.x;
	initParticleData.bufferVelByteStride	= sizeof(ParticleSDK);

	//Setup fluid descriptor
	NxFluidDesc fluidDesc;
	fluidDesc.maxParticles                  	= initParticlesNum;
	fluidDesc.kernelRadiusMultiplier			= KERNEL_RADIUS_MULTIPLIER;
	fluidDesc.restParticlesPerMeter				= REST_PARTICLES_PER_METER;
	fluidDesc.collisionDistanceMultiplier   	= COLLISION_DISTANCE_MULTIPLIER;
	fluidDesc.stiffness							= 50.0f;
	fluidDesc.viscosity							= 22.0f;
	fluidDesc.damping							= 0.0f;
	fluidDesc.restitutionForStaticShapes		= 0.4f;
	fluidDesc.dynamicFrictionForStaticShapes	= 0.03f;
	fluidDesc.simulationMethod					= NX_F_SPH; //NX_F_NO_PARTICLE_INTERACTION;

	if (!gHardwareSimulation)
		fluidDesc.flags &= ~NX_FF_HARDWARE;

	fluidDesc.initialParticleData			= initParticleData;

	//Create user fluid.
	//- create NxFluid in NxScene
	//- setup the buffers to read from data from the SDK
	//- set NxFluid::userData field to MyFluid instance
	bool trackUserData = false;
	bool provideCollisionNormals = false;
	MyFluid* fluid = new MyFluid(gScene, fluidDesc, trackUserData, provideCollisionNormals, NxVec3(0.2f,0.3f,0.7f), 0.03f);
	assert(fluid);
	gMyFluids.pushBack(fluid);

	delete[] initParticles;

	gCameraPos.set(23, 14, 23);
	gCameraForward = fluidPos - NxVec3(0, 3, 0) - gCameraPos;
	gCameraForward.normalize();

}
Пример #9
0
void render()
{
	static Timer t;
	if(!gMyPhysX.isPaused())
	{
		for (NxU32 i = 0; i < gKinematicActors.size(); i++)
		{
			NxActor* actor = gKinematicActors[i].actor;
			NxVec3 pos = actor->getGlobalPosition();
			pos += gKinematicActors[i].vel * 1.f/60.f;
			actor->moveGlobalPosition(pos);
		}
	}	
	gMyPhysX.simulate(t.elapsed_time());
	t.reset(); 
	// Clear buffers
	glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);

	glColor4f(0.5,0.9,0.5,1.0);
	DrawSkyBox(SKYEXTENTS);
	drawPlane(SKYEXTENTS);
	// Keep physics & graphics in sync
	for (NxU32 pass = 0; pass < 2; pass++) {
		int nbActors = gMyPhysX.getScene()->getNbActors();
		NxActor** actors = gMyPhysX.getScene()->getActors();
		actors += nbActors;
		while(nbActors--)
		{
			NxActor* actor = *--actors;

			float size;
			bool isTrigger = false;
			bool isKinematic = actor->isDynamic() && actor->readBodyFlag(NX_BF_KINEMATIC);
			NxVec3 color;
			NxF32 alpha = 1;
			if (actor->isDynamic()) {
				if (actor->readBodyFlag(NX_BF_KINEMATIC)) {
					color.set(1,0,0);
				} else {
					color.set(0,1,0);
				}
			} else {
				color.set(0.2f,0.2f,0.2f);
			}

			if (*(int *)(&actor->userData) < 0)
			{
				NxI32 triggerNumber = -(*(NxI32 *)(&actor->userData));
				NxI32 triggerIndex = triggerNumber - 1;
				// This is our trigger
				isTrigger = true;

				size = 10.0f;
				color.z = gNbTouchedBodies[triggerIndex] > 0.5f ? 1.0f:0.0f;
				alpha = 0.5f;
				if (pass == 0)
					continue;
			}
			else
			{
				// This is a normal object
				size = float(*(int *)(&actor->userData));
				if (pass == 1)
					continue;
			}
			float glmat[16];
			glPushMatrix();
			actor->getGlobalPose().getColumnMajor44(glmat);
			glMultMatrixf(glmat);
			glColor4f(color.x, color.y, color.z, 1.0f);
			glutSolidCube(size*2.0f);
			glPopMatrix();

			// Handle shadows
			if( !isTrigger)
			{
				glPushMatrix();

				const static float ShadowMat[]={ 1,0,0,0, 0,0,0,0, 0,0,1,0, 0,0,0,1 };

				glMultMatrixf(ShadowMat);
				glMultMatrixf(glmat);

				glDisable(GL_LIGHTING);
				glColor4f(0.1f, 0.2f, 0.3f, 1.0f);
				glutSolidCube(size*2.0f);
				glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
				glEnable(GL_LIGHTING);

				glPopMatrix();
			}
		}
	}
}