Beispiel #1
0
void renderclip(entity &e)
{
    float xradius = max(float(e.attr2), 0.1f), yradius = max(float(e.attr3), 0.1f);
    vec bbmin(e.x - xradius, e.y - yradius, float(S(e.x, e.y)->floor+e.attr1)),
        bbmax(e.x + xradius, e.y + yradius, bbmin.z + max(float(e.attr4), 0.1f));

    glDisable(GL_TEXTURE_2D);
    switch(e.type)
    {
        case CLIP:     linestyle(1, 0xFF, 0xFF, 0); break;  // yellow
        case MAPMODEL: linestyle(1, 0, 0xFF, 0);    break;  // green
        case PLCLIP:   linestyle(1, 0xFF, 0, 0xFF); break;  // magenta
        default:       linestyle(1, 0xFF, 0, 0);    break;  // red
    }
    glBegin(GL_LINES);

    glVertex3f(bbmin.x, bbmin.y, bbmin.z);
    loopi(2) glVertex3f(bbmax.x, bbmin.y, bbmin.z);
    loopi(2) glVertex3f(bbmax.x, bbmax.y, bbmin.z);
    loopi(2) glVertex3f(bbmin.x, bbmax.y, bbmin.z);
    glVertex3f(bbmin.x, bbmin.y, bbmin.z);

    glVertex3f(bbmin.x, bbmin.y, bbmax.z);
    loopi(2) glVertex3f(bbmax.x, bbmin.y, bbmax.z);
    loopi(2) glVertex3f(bbmax.x, bbmax.y, bbmax.z);
    loopi(2) glVertex3f(bbmin.x, bbmax.y, bbmax.z);
    glVertex3f(bbmin.x, bbmin.y, bbmax.z);

    loopi(8) glVertex3f(i&2 ? bbmax.x : bbmin.x, i&4 ? bbmax.y : bbmin.y, i&1 ? bbmax.z : bbmin.z);

    glEnd();
    glEnable(GL_TEXTURE_2D);
}
void onMouseDrag( GLFWwindow* window, double fx, double fy)
{
	int x=fx;
	int y=fy;
#else
void onMouseDrag( int x, int y)
{
#endif
	if (isDrag) 
	{
		printf( "in drag mode %d\n", isDrag);
		if (isDrag==V_DRAG && cowFlag)
		{
			// vertical dragging
			// TODO:
			// create a dragging plane perpendicular to the ray direction, 
			// and test intersection with the screen ray.
      // When dragged just change Y position
			Ray ray;
			screenCoordToRay(clickX, y, ray);
			PickInfo &pp=pickInfo;
			std::pair<bool, double> c=ray.intersects(dragPlane);

			vector3 currentPos=ray.getPoint(c.second);	

      matrix4 T;
      T.setTranslation(currentPos - pp.cowPickPosition, false);
      cow2wld.mult(T, pp.cowPickConfiguration);
		}
		else
		{ 
			// horizontal dragging
			// Hint: read carefully the following block to implement vertical dragging.
			if(cursorOnCowBoundingBox)
			{
				Ray ray;
				screenCoordToRay(x, y, ray);
				PickInfo &pp=pickInfo;
				Plane p(vector3(0,1,0), pp.cowPickPosition);
				std::pair<bool, double> c=ray.intersects(p);

				vector3 currentPos=ray.getPoint(c.second);	

				matrix4 T;
				T.setTranslation(currentPos-pp.cowPickPosition, false);
				cow2wld.mult(T, pp.cowPickConfiguration);
			}
		}
	}
	else
	{
		Ray ray;
		screenCoordToRay(x, y, ray);

		std::vector<Plane> planes;
		vector3 bbmin(cow->bbmin.x, cow->bbmin.y, cow->bbmin.z);
		vector3 bbmax(cow->bbmax.x, cow->bbmax.y, cow->bbmax.z);

		planes.push_back(makePlane(bbmin, bbmax, vector3(0,1,0)));
		planes.push_back(makePlane(bbmin, bbmax, vector3(0,-1,0)));
		planes.push_back(makePlane(bbmin, bbmax, vector3(1,0,0)));
		planes.push_back(makePlane(bbmin, bbmax, vector3(-1,0,0)));
		planes.push_back(makePlane(bbmin, bbmax, vector3(0,0,1)));
		planes.push_back(makePlane(bbmin, bbmax, vector3(0,0,-1)));


		std::pair<bool,double> o=ray.intersects(planes);
		cursorOnCowBoundingBox=o.first;
		PickInfo &pp=pickInfo;
		pp.cursorRayT=o.second;
		pp.cowPickPosition=ray.getPoint(pp.cursorRayT);
		pp.cowPickConfiguration=cow2wld;
		matrix4 invWorld;
		invWorld.inverse(cow2wld);
		// the local position (relative to the cow frame) of the pick position.
		pp.cowPickPositionLocal=invWorld*pp.cowPickPosition;
	}

}

/*********************************************************************************
* Call this part whenever user types keyboard. 
**********************************************************************************/
#if GLFW_VERSION_MAJOR==3
void onKeyPress(GLFWwindow *__win, int key, int __scancode, int action, int __mods)
#else
void onKeyPress( int key, int action)
#endif
{
	if (action==GLFW_RELEASE)
		return 	; // do nothing
	// If 'c' or space bar are pressed, alter the camera.
	// If a number is pressed, alter the camera corresponding the number.
	if ((key == ' ') || (key == 'c'))
	{    
		printf( "Toggle camera %d\n", cameraIndex );
		cameraIndex += 1;
	}      
	else if ((key >= '0') && (key <= '9'))
		cameraIndex = key - '0';

	if (cameraIndex >= (int)wld2cam.size() )
		cameraIndex = 0;
}
void screenCoordToRay(int x, int y, Ray& ray)
{
	int height , width;
#if GLFW_VERSION_MAJOR==3
	glfwGetWindowSize(g_window, &width, &height);
#else
	glfwGetWindowSize(&width, &height);
#endif

	matrix4 matProjection;
	matProjection.getCurrentOpenGLmatrix(GL_PROJECTION_MATRIX);
	matProjection*=wld2cam[cameraIndex];
	matrix4 invMatProjection;
	invMatProjection.inverse(matProjection);

	vector3 vecAfterProjection, vecAfterProjection2;
	// -1<=v.x<1 when 0<=x<width
	// -1<=v.y<1 when 0<=y<height
	vecAfterProjection.x = ((double)(x - 0)/(double)width)*2.0-1.0;
	vecAfterProjection.y = ((double)(y - 0)/(double)height)*2.0-1.0;
	vecAfterProjection.y*=-1;
	vecAfterProjection.z = -10;

	//std::cout<<"cowPosition in clip coordinate (NDC)"<<matProjection*cow2wld.getTranslation()<<std::endl;
	
	vector3 vecBeforeProjection=invMatProjection*vecAfterProjection;

	// camera position
	ray.origin()=cam2wld[cameraIndex].getTranslation();
	ray.direction()=vecBeforeProjection-ray.origin();
	ray.direction().normalize();

	//std::cout<<"dir" <<ray.direction()<<std::endl;

}
Beispiel #3
0
void	VoronoiFractureDemo::initPhysics()
{
	srand(13);
	useGenericConstraint = !useGenericConstraint;
	printf("useGenericConstraint = %d\n", useGenericConstraint);

	
	setTexturing(true);
	setShadows(true);

	setCameraDistance(btScalar(20.));

	///collision configuration contains default setup for memory, collision setup
	m_collisionConfiguration = new btDefaultCollisionConfiguration();
	//m_collisionConfiguration->setConvexConvexMultipointIterations();

	///use the default collision dispatcher. For parallel processing you can use a diffent dispatcher (see Extras/BulletMultiThreaded)
	m_dispatcher = new	btCollisionDispatcher(m_collisionConfiguration);
	
	useMpr = 1 - useMpr;

	if (useMpr)
	{
		printf("using GJK+MPR convex-convex collision detection\n");
		btConvexConvexMprAlgorithm::CreateFunc* cf = new btConvexConvexMprAlgorithm::CreateFunc;
		m_dispatcher->registerCollisionCreateFunc(CONVEX_HULL_SHAPE_PROXYTYPE, CONVEX_HULL_SHAPE_PROXYTYPE, cf);
		m_dispatcher->registerCollisionCreateFunc(CONVEX_HULL_SHAPE_PROXYTYPE, BOX_SHAPE_PROXYTYPE, cf);
		m_dispatcher->registerCollisionCreateFunc(BOX_SHAPE_PROXYTYPE, CONVEX_HULL_SHAPE_PROXYTYPE, cf);
	}
	else
	{
		printf("using default (GJK+EPA) convex-convex collision detection\n");
	}
	
	m_broadphase = new btDbvtBroadphase();

	///the default constraint solver. For parallel processing you can use a different solver (see Extras/BulletMultiThreaded)
	btSequentialImpulseConstraintSolver* sol = new btSequentialImpulseConstraintSolver;
	m_solver = sol;

	m_dynamicsWorld = new btDiscreteDynamicsWorld(m_dispatcher,m_broadphase,m_solver,m_collisionConfiguration);
	m_dynamicsWorld->getSolverInfo().m_splitImpulse = true;
	m_dynamicsWorld->setDebugDrawer(&sDebugDraw);
	
	m_dynamicsWorld->setGravity(btVector3(0,-10,0));

	///create a few basic rigid bodies
	btCollisionShape* groundShape = new btBoxShape(btVector3(btScalar(50.),btScalar(50.),btScalar(50.)));
//	btCollisionShape* groundShape = new btStaticPlaneShape(btVector3(0,1,0),50);
	
	m_collisionShapes.push_back(groundShape);

	btTransform groundTransform;
	groundTransform.setIdentity();
	groundTransform.setOrigin(btVector3(0,-50,0));

	//We can also use DemoApplication::localCreateRigidBody, but for clarity it is provided here:
	{
		btScalar mass(0.);

		//rigidbody is dynamic if and only if mass is non zero, otherwise static
		bool isDynamic = (mass != 0.f);

		btVector3 localInertia(0,0,0);
		if (isDynamic)
			groundShape->calculateLocalInertia(mass,localInertia);

		//using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects
		btDefaultMotionState* myMotionState = new btDefaultMotionState(groundTransform);
		btRigidBody::btRigidBodyConstructionInfo rbInfo(mass,myMotionState,groundShape,localInertia);
		btRigidBody* body = new btRigidBody(rbInfo);

		//add the body to the dynamics world
		m_dynamicsWorld->addRigidBody(body);
	}

	{
		btCollisionShape* groundShape = new btBoxShape(btVector3(btScalar(10.),btScalar(8.),btScalar(1.)));
		btScalar mass(0.);

		//rigidbody is dynamic if and only if mass is non zero, otherwise static
		bool isDynamic = (mass != 0.f);

		btVector3 localInertia(0,0,0);
		if (isDynamic)
			groundShape->calculateLocalInertia(mass,localInertia);
		groundTransform.setOrigin(btVector3(0,0,0));
		//using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects
		btDefaultMotionState* myMotionState = new btDefaultMotionState(groundTransform);
		btRigidBody::btRigidBodyConstructionInfo rbInfo(mass,myMotionState,groundShape,localInertia);
		btRigidBody* body = new btRigidBody(rbInfo);

		//add the body to the dynamics world
		m_dynamicsWorld->addRigidBody(body);
	}

	// ==> Voronoi Shatter Basic Demo: Random Cuboid

	// Random size cuboid (defined by bounding box max and min)
	btVector3 bbmax(btScalar(rand() / btScalar(RAND_MAX)) * 12. +0.5, btScalar(rand() / btScalar(RAND_MAX)) * 1. +0.5, btScalar(rand() / btScalar(RAND_MAX)) * 1. +0.5);
	btVector3 bbmin = -bbmax;
	// Place it 10 units above ground
	btVector3 bbt(0,15,0);
	// Use an arbitrary material density for shards (should be consitent/relative with/to rest of RBs in world)
	btScalar matDensity = 1;
	// Using random rotation
	btQuaternion bbq(btScalar(rand() / btScalar(RAND_MAX)) * 2. -1.,btScalar(rand() / btScalar(RAND_MAX)) * 2. -1.,btScalar(rand() / btScalar(RAND_MAX)) * 2. -1.,btScalar(rand() / btScalar(RAND_MAX)) * 2. -1.);
	bbq.normalize();
	// Generate random points for voronoi cells
	btAlignedObjectArray<btVector3> points;
	btVector3 point;
	btVector3 diff = bbmax - bbmin;
	for (int i=0; i < VORONOIPOINTS; i++) {
		// Place points within box area (points are in world coordinates)
		point = quatRotate(bbq, btVector3(btScalar(rand() / btScalar(RAND_MAX)) * diff.x() -diff.x()/2., btScalar(rand() / btScalar(RAND_MAX)) * diff.y() -diff.y()/2., btScalar(rand() / btScalar(RAND_MAX)) * diff.z() -diff.z()/2.)) + bbt;
		points.push_back(point);
	}
	m_perfmTimer.reset();
	voronoiBBShatter(points, bbmin, bbmax, bbq, bbt, matDensity);
	printf("Total Time: %f seconds\n", m_perfmTimer.getTimeMilliseconds()/1000.);
	
	for (int i=m_dynamicsWorld->getNumCollisionObjects()-1; i>=0 ;i--)
	{
		btCollisionObject* obj = m_dynamicsWorld->getCollisionObjectArray()[i];
		obj->getCollisionShape()->setMargin(CONVEX_MARGIN+0.01);
	}
	m_dynamicsWorld->performDiscreteCollisionDetection();

	for (int i=m_dynamicsWorld->getNumCollisionObjects()-1; i>=0 ;i--)
	{
		btCollisionObject* obj = m_dynamicsWorld->getCollisionObjectArray()[i];
		obj->getCollisionShape()->setMargin(CONVEX_MARGIN);
	}

	attachFixedConstraints();

}