Beispiel #1
0
void btGImpactMeshShapePart::processAllTrianglesRay(btTriangleCallback* callback,const btVector3& rayFrom, const btVector3& rayTo) const
{
	lockChildShapes();

	btAlignedObjectArray<int> collided;
	btVector3 rayDir(rayTo - rayFrom);
	rayDir.normalize();
	m_box_set.rayQuery(rayDir, rayFrom, collided);

	if(collided.size()==0)
	{
		unlockChildShapes();
		return;
	}

	int part = (int)getPart();
	btPrimitiveTriangle triangle;
	int i = collided.size();
	while(i--)
	{
		getPrimitiveTriangle(collided[i],triangle);
		callback->processTriangle(triangle.m_vertices,part,collided[i]);
	}
	unlockChildShapes();
}
Beispiel #2
0
void Physics::update(Game *game)
{
	// Prepare for simulation. Typically we use a time step of 1/60 of a
	// second (60Hz) and 10 iterations. This provides a high quality simulation
	// in most game scenarios.
	float32 timeStep = 1.0f / 60.0f;
	int32 velocityIterations = 6;
	int32 positionIterations = 2;

	// This is our little game loop.
	for (int32 i = 0; i < 60; ++i)
	{
		// Instruct the world to perform a single step of simulation.
		// It is generally best to keep the time step and iterations fixed.
		box2DWorld->Step(timeStep, velocityIterations, positionIterations);
	}

	list<b2Body*>::iterator bodiesIterator;
	bodiesIterator = bodiesToDestroy.begin();
	while (bodiesIterator != bodiesToDestroy.end())
	{
		b2Body* body = *bodiesIterator;
		bodiesIterator++;
		box2DWorld->DestroyBody(body);
 	}
	bodiesToDestroy.clear();

	if(explosionThisFrame)
	{
		list<Explosion*>::iterator explosionsIterator;
		explosionsIterator = explosions.begin();
		while (explosionsIterator != explosions.end())
		{
			Explosion* explosion = *explosionsIterator;
			explosionsIterator++;

			int numRays = explosion->numOfRays;
			b2Vec2 center = explosion->explosionEpicenter;
			float blastRadius = explosion->blastRadius; 
			for (int i = 0; i < numRays; i++) 
			{
				float angle = (i / (float)numRays) * 360 * DEGTORAD;
				b2Vec2 rayDir( sinf(angle), cosf(angle) );
				b2Vec2 rayEnd = center + pixelsToMeters(blastRadius) * rayDir;

				//check what this ray hits
				ExplosionCallback callback;//basic callback to record body and hit point
				box2DWorld->RayCast(&callback, center, rayEnd);
				if ( callback.getClosestFixture() ) 
					applyBlastImpulse(callback.getClosestFixture()->GetBody(), center, callback.getImplusePoint(), (explosion->blastPower / (float)numRays));
			}
		}
		explosions.clear();
		explosionThisFrame = false;
	}
}
Beispiel #3
0
//----------------------------------------------------------------------------------------------------------------------
ngl::Vec3 NGLDraw::getWorldSpace(const int _x, const int _y)
{

    ngl::Mat4 m;
    m = m*m_mouseGlobalTX;
    ngl::Mat4 t=m_cam->getProjectionMatrix();
    ngl::Mat4 v=m_cam->getViewMatrix();

    // as ngl:: and OpenGL use different formats need to transpose the matrix.
    t.transpose();
    v.transpose();
    m.transpose();
    ngl::Mat4 inverse=(t*v*m).inverse();

    ngl::Vec4 tmp(0,0,-1.0f,1.0f);
    // convert into NDC
    tmp.m_x=(2.0f * _x) / m_width- 1.0f;
    tmp.m_y=1.0f - (2.0f * _y) / m_height;
    // scale by inverse MV * Project transform

    ngl::Vec4 near(tmp.m_x,tmp.m_y,-1.0f,1.0f);
    ngl::Vec4 far(tmp.m_x,tmp.m_y,1.0f,1.0f);
    //get world point on near and far clipping planes
    ngl::Vec4 obj_near=inverse*near;
    ngl::Vec4 obj_far=inverse*far;

    // Scale by w
    obj_near/=obj_near.m_w;
    obj_far/=obj_far.m_w;

    ngl::Vec3 nearPoint(obj_near.m_x,obj_near.m_y,obj_near.m_z);
    ngl::Vec3 farPoint(obj_far.m_x,obj_far.m_y,obj_far.m_z);

    //create ray
    ngl::Vec3 rayDir(farPoint-nearPoint);
    if(rayDir.lengthSquared() == 0.0f)
    {
        std::cout<<"Ray Direction in getWorldSpace equals zero, can't normalise"<<std::endl;
    }
    else
    {
        rayDir.normalize();
    }

    //calculate distance to zx plane
    float dist = (-nearPoint.m_y)/rayDir.m_y;

    //set world space coordinate where y = 0
    ngl::Vec3 obj(nearPoint.m_x + (dist*rayDir.m_x),nearPoint.m_y + (dist*rayDir.m_y),nearPoint.m_z + (dist*rayDir.m_z));

    obj.m_y = 0.0;

    return obj;
}
Beispiel #4
0
/**
 * Picks a single scene object from the scene. If the object has a mesh collider, the picker will calculate the
 * texture coordinates and barycentric coordinates of the corresponding hit-point. Note that this will do nothing
 * if the scene object doesn't have a collider.
 */
void Picker::pickSceneObject(const SceneObject *scene_object, float ox, float oy, float oz, float dx, float dy, float dz, ColliderData &colliderData){
    Collider* collider = scene_object->collider();
    if(collider == nullptr){
        return;
    }
    else if (collider->enabled() && scene_object->enabled()) {
        glm::vec3 rayStart(ox, oy, oz);
        glm::vec3 rayDir(dx, dy, dz);

        colliderData = collider->isHit(rayStart, rayDir);
    }
}
Beispiel #5
0
static Eigen::Vector3d mapToSphere(
	Eigen::Matrix4d invProjMatrix, 
	Eigen::Vector2d const p, 
	Eigen::Vector3d viewSphereCenter, 
	double viewSpaceRadius) {

	Eigen::Vector4d viewP = invProjMatrix * Eigen::Vector4d(p(0), p(1), -1.0, 1.0);
	//viewP(0) /= viewP(3);
	//viewP(1) /= viewP(3);
	//viewP(2) /= viewP(3);

	Eigen::Vector3d rayOrigin(0.0, 0.0, 0.0);
	Eigen::Vector3d rayDir(viewP(0), viewP(1), viewP(2));
	rayDir.normalize();

	Eigen::Vector3d CO = rayOrigin - viewSphereCenter;

	double a = 1.0;
	double bPrime = CO.dot(rayDir);
	double c = CO.dot(CO) - viewSpaceRadius * viewSpaceRadius;

	double delta = bPrime * bPrime - a * c;

	if (delta < 0.0) {
		double t = -CO.z() / rayDir.z();
		Eigen::Vector3d point = rayOrigin + t * rayDir;
		Eigen::Vector3d dir = point - viewSphereCenter;
		dir.normalize();
		return viewSphereCenter + dir * viewSpaceRadius;
	}

	double root[2] = { (-bPrime - sqrt(delta)) / a, (-bPrime + sqrt(delta)) / a };

	if (root[0] >= 0.0) {
		Eigen::Vector3d intersectionPoint = rayOrigin + root[0] * rayDir;
		return intersectionPoint;
	}
	else if (root[1] >= 0.0) {
		Eigen::Vector3d intersectionPoint = rayOrigin + root[1] * rayDir;
		return intersectionPoint;
	}
	else {
		double t = -CO.z() / rayDir.z();
		Eigen::Vector3d point = rayOrigin + t * rayDir;
		Eigen::Vector3d dir = point - viewSphereCenter;
		dir.normalize();
		return viewSphereCenter + dir * viewSpaceRadius;
	}
}
std::vector<vec3> Orthographic::render(std::vector<std::unique_ptr<WorldObject>> &objects,
									   std::vector<std::unique_ptr<Light>> &lights,
									   vec2 imageSize, double imageAspectRatio, int aaDepth) {
	std::vector<vec3> frameBuffer;
	for (int y = 0; y < imageSize.y; y++) {
		for (int x = 0; x < imageSize.x; x++) {
			vec3 pixel;
			std::vector<vec3> aaData;
			for (int aay = 0; aay < aaDepth; aay++) {
				for (int aax = 0; aax < aaDepth; aax++) {
					// normalize ray pos (-> NDC)
					// add 0.5 so that the final ray passes through the middle of the pixel
					pixel.x = (x + ((1.0 / (aaDepth - 1.0)) * aax)) / imageSize.x;
					pixel.y = (y + ((1.0 / (aaDepth - 1.0)) * aay)) / imageSize.y;

					// map from [0;1] to [-imageAspectRatio;imageAspectRatio]
					pixel.x = 2.0 * pixel.x - 1.0;
					pixel.x *= imageAspectRatio;
					pixel.y = 1.0 - 2.0 * pixel.y;

					double scale = tan(MyMath::degToRad(fov / 2.0));
					pixel.x *= scale;
					pixel.y *= scale;

					vec3 rayOrig(-pixel.x, -pixel.y, 0.0f);
					vec3 rayDir(0.0f, 0.0f, -1.0f);
					rayDir -= rayOrig;
					rayDir = rayDir.normalize();

					Ray ray(rayOrig, rayDir);
					aaData.push_back(ray.cast(objects, lights, 3));
				}
			}

			vec3 sum;
			for (vec3 color : aaData) {
				sum += color;
			}
			sum = sum / aaData.size();
			frameBuffer.push_back(sum);
		}
	}

	return frameBuffer;
}
Beispiel #7
0
/*
 * Pick against the scene bounding box.
 * The input ray is in world coordinates.
 * To pick against the bounding box, we create a bounding box mesh
 * from the original mesh. This new mesh is in mesh coordinates
 * so we must apply the inverse of the model matrix from the scene object
 * to the ray to put it into mesh coordinates.
 */
glm::vec3 Picker::pickSceneObjectAgainstBoundingBox(const SceneObject* scene_object, float ox, float oy, float oz, float dx, float dy, float dz) {
    RenderData* rd = scene_object->render_data();

    if ((rd == NULL) || (rd->mesh() == NULL)) {
        return glm::vec3(std::numeric_limits<float>::infinity());
    }
    glm::mat4 model_inverse = glm::affineInverse(scene_object->transform()->getModelMatrix());
    const BoundingVolume& bounds = rd->mesh()->getBoundingVolume();
    glm::vec3 rayStart(ox, oy, oz);
    glm::vec3 rayDir(dx, dy, dz);

    glm::normalize(rayDir);
    Collider::transformRay(model_inverse, rayStart, rayDir);
    ColliderData data = MeshCollider::isHit(bounds, rayStart, rayDir);
    if (data.IsHit) {
        return data.HitPosition;
    }
    return glm::vec3(std::numeric_limits<float>::infinity());
}
Beispiel #8
0
DecoColor Shading(const vector3& realIntersectPt, const vector3& norm, const vector3& lightPos, const vector3& viewPos,
				  const vector3& lightDiffuse, const vector3& lightSpecular, const vector3& lightAmbient, 
				  const vector3& matDiffuse, const vector3& matSpecular, const vector3&matAmbient)
{
	vector3 col(0, 0, 0);
	vector3 rayDir(lightPos - realIntersectPt);
	vector3 viewDir(viewPos - realIntersectPt);
	vector3 normal = norm;
	viewDir.normalize();
	rayDir.normalize();
	normal.normalize();
	vector3 halfDir = (viewDir + rayDir) / 2;
	halfDir.normalize();

	col += vector3(lightDiffuse.x * matDiffuse.x, lightDiffuse.y * matDiffuse.y, lightDiffuse.z * matDiffuse.z) * max(0.0, DotProduct(normal, rayDir));
	//col += vector3(lightAmbient.x * matAmbient.x, lightAmbient.y * matAmbient.y, lightAmbient.z * matAmbient.z);
	DOUBLE dotHalfAngle = max(0.0, DotProduct(halfDir, normal));
	col += vector3(lightSpecular.x * matSpecular.x, lightSpecular.y * matSpecular.y, lightSpecular.z * matSpecular.z) * dotHalfAngle * dotHalfAngle;
	return DecoColor(vector4(col.x, col.y, col.z, 1));
}
bool ComTerrain::GetHeight(float & height, const D3DXVECTOR3 & pos)
{
	D3DXVECTOR3 rayPos(pos.x, pos.y + m_rayDistance, pos.z);
	D3DXVECTOR3 rayDir(0, -1, 0);
	float distance = 0.0f;

	for (int i = 0; i < m_vecIndices.size(); i += 3)
	{
		D3DXVECTOR3 v1 = m_vecVertices[m_vecIndices[i]].p;
		D3DXVECTOR3 v2 = m_vecVertices[m_vecIndices[i + 1]].p;
		D3DXVECTOR3 v3 = m_vecVertices[m_vecIndices[i + 2]].p;

		if (D3DXIntersectTri(&v1, &v2, &v3, &rayPos, &rayDir, NULL, NULL, &distance))
		{
			height = rayPos.y - distance;
			return true;
		}
	}

	return false;
}
Beispiel #10
0
void Bomb::explode() {
	if (exploded == false) {
		exploded = true;
		b2Vec2 center = bodies[0].body_ptr->GetPosition();
		float power = 300; 
		float blast_radius = 15;
		//apply impulse to bodies
		size_t rays = 50;
	    for (size_t i = 0; i < rays; i++) {
            float angle = (i / (float)rays) * 6.282;
            b2Vec2 rayDir( sinf(angle), cosf(angle) );
            b2Vec2 rayEnd = center + blast_radius * rayDir;

            //check what this ray hits
            RayCastClosestCallback callback;
            world.RayCast(&callback, center, rayEnd);
            if ( callback.m_body ) {
                applyImpulse(callback.m_body, center, callback.m_point, power);
            }
        }
	}	
}
Beispiel #11
0
bool ConvexShape::castRay( const Point3F &start, const Point3F &end, RayInfo *info )
{
   if ( mPlanes.empty() )
      return false;   

   const Vector< PlaneF > &planeList = mPlanes;
   const U32 planeCount = planeList.size();  

   F32 t;
   F32 tmin = F32_MAX;
   S32 hitFace = -1;
   Point3F hitPnt, pnt;
   VectorF rayDir( end - start );
   rayDir.normalizeSafe();

   if ( false )
   {
      PlaneF plane( Point3F(0,0,0), Point3F(0,0,1) );
      Point3F sp( 0,0,-1 );
      Point3F ep( 0,0,1 );

      F32 t = plane.intersect( sp, ep );
      Point3F hitPnt;
      hitPnt.interpolate( sp, ep, t );
   }

   for ( S32 i = 0; i < planeCount; i++ )
   {
      // Don't hit the back-side of planes.
      if ( mDot( rayDir, planeList[i] ) >= 0.0f )
         continue;

      t = planeList[i].intersect( start, end );

      if ( t >= 0.0f && t <= 1.0f && t < tmin )
      {
         pnt.interpolate( start, end, t );

         S32 j = 0;
         for ( ; j < planeCount; j++ )
         {
            if ( i == j )
               continue;

            F32 dist = planeList[j].distToPlane( pnt );
            if ( dist > 1.0e-004f )
               break;
         }

         if ( j == planeCount )
         {
            tmin = t;
            hitFace = i;
         }
      }
   }

   if ( hitFace == -1 )
      return false;

   info->face = hitFace;            
   info->material = mMaterialInst;
   info->normal = planeList[ hitFace ];
   info->object = this;
   info->t = tmin;

   //mObjToWorld.mulV( info->normal );

   return true;
}
Beispiel #12
0
void PhysicalCamera::grasp()
{
    if (!mGraspedObject)
    {
        // Fire a ray into the scene to find an object to grasp.  If
        // an object is found, attach it to the grasping Motor and,
        // if using long range grasping mode, store the intersection
        // position relative to the camera as the grasp offset.

        // First update the ray casting Sensor's ray.
        Ogre::Vector3 camForward = mOgreCamera->getDerivedDirection();
        if (0 != camForward.squaredLength())
        {
            camForward.normalise();
        }
        opal::Vec3r rayDir(camForward[0], camForward[1],
                           camForward[2]);
        if (PHYSICAL == mType)
        {
            // The ray's origin will be updated automatically since
            // it is attached to the camera's Solid.  Its direction
            // should be set manually here because we constantly
            // reset the camera's orientation.
            opal::Point3r dummyPoint;
            opal::Rayr r(dummyPoint, rayDir);
            mGraspingSensor->setRay(r);
        }
        else
        {
            // The ray should start at the camera's position and fire
            // straight forward into the scene.
            Ogre::Vector3 ogreCamPos = mOgreCamera->getDerivedPosition();
            opal::Point3r opalCamPos(ogreCamPos[0], ogreCamPos[1],
                                     ogreCamPos[2]);
            opal::Rayr r(opalCamPos, rayDir);
            mGraspingSensor->setRay(r);
        }

        // Fire the ray.
        opal::RaycastResult result =
            mGraspingSensor->fireRay(mMaxReach);

        if (result.solid) // && !result.solid->isStatic())
        {
            // Store the grasped object.
            mGraspedObject = result.solid;

            // Initialize the grasping Motor with the new data.
            opal::SpringMotorData data;
            data.solid = result.solid;
            data.mode = mGraspingMotorMode;
            data.linearKs = mGraspingLinearKs;
            data.linearKd = mGraspingLinearKd;
            data.angularKs = mGraspingAngularKs;
            data.angularKd = mGraspingAngularKd;

            opal::Matrix44r solidTransform = result.solid->getTransform();
            //data.desiredUp = solidTransform.getUp();
            //data.desiredForward = solidTransform.getForward();
            //data.desiredRight = solidTransform.getRight();
            // Desired position will be updated in the "update"
            // function.
            mGraspingMotor->init(data);

            if (PHYSICAL == mType)
            {
                //// Grab it where the ray intersected it.
                //mGraspingMotor->setGlobalAttachPoint(result.intersection);

                // Just grab it in the middle.
                mGraspingMotor->setGlobalAttachPoint(result.solid->
                                                     getPosition());
            }
            else
            {
                mGraspingMotor->setGlobalAttachPoint(result.intersection);

                // Set the offset (from the camera) to be the same distance
                // as when it was grasped.
                mPhysicalGraspOffset.set(0, 0, -result.distance);
            }

            // Compute the grasped object's offset transform from the camera
            // which is only used for desired orientation.
            Ogre::Matrix4 ogreMat;
            mOgreCamera->getParentSceneNode()->getWorldTransforms(&ogreMat);
            opal::Matrix44r camTransform(
                ogreMat[0][0], ogreMat[1][0], ogreMat[2][0], ogreMat[3][0],
                ogreMat[0][1], ogreMat[1][1], ogreMat[2][1], ogreMat[3][1],
                ogreMat[0][2], ogreMat[1][2], ogreMat[2][2], ogreMat[3][2],
                ogreMat[0][3], ogreMat[1][3], ogreMat[2][3], ogreMat[3][3]);
            camTransform.invert();
            opal::Matrix44r objTransInv = mGraspedObject->getTransform();
            objTransInv.invert();
            mGraspedObjectOffsetTransform = objTransInv * camTransform;

            // Set the desired transform for orientation only (the position
            // part should be overwritten below).
            opal::Matrix44r desiredObjTransform = mGraspedObjectOffsetTransform *
                                                  camTransform;
            desiredObjTransform.invert();
            mGraspingMotor->setDesiredTransform(desiredObjTransform);

            // Update the the desired position.
            mGraspingMotor->setDesiredPosition(getGraspGlobalPos());

            // Apply extra angular damping.
            result.solid->setAngularDamping(3);
        }
    }
}