Пример #1
0
 btVector3 PhysicsSystem::getRayPoint(float extent, float mouseX, float mouseY)
 {
     //get a ray pointing to the center of the viewport
     Ray centerRay = mRender.getCamera()->getCameraToViewportRay(mouseX, mouseY);
     btVector3 result(centerRay.getPoint(500*extent).x,-centerRay.getPoint(500*extent).z,centerRay.getPoint(500*extent).y); /// \todo make this distance (ray length) configurable
     return result;
 }
Пример #2
0
    Intersection Triangle::intersect(const Ray &r) const
    {
         const Vec3t edge1(V1-V0), edge2(V2-V0); // could precalculate
         Vec3t pvec(cross(r.getNormal(), edge2));
         DefType det=dot(edge1,pvec);

         if (det < MM_EPSILON)
             return Intersection();

         Vec3t tvec(r.getPoint()-V0);
         DefType u=dot(tvec,pvec);

         if (u < 0 || u > det)
             return Intersection();

         Vec3t qvec(cross(tvec,edge1));

         DefType v=dot(r.getPoint(),qvec);

         if (v < 0 || u+v > det)
             return Intersection();

         DefType t=dot(edge2, qvec)/det;

         return Intersection(r.positionAtTime(t), m_normal, t, true, true);
    }
Пример #3
0
    std::vector < std::pair <float, std::string> > PhysicsSystem::getFacedObjects ()
    {
        //get a ray pointing to the center of the viewport
        Ray centerRay = mRender.getCamera()->getCameraToViewportRay(
        mRender.getViewport()->getWidth()/2,
        mRender.getViewport()->getHeight()/2);
        btVector3 from(centerRay.getOrigin().x,-centerRay.getOrigin().z,centerRay.getOrigin().y);
        btVector3 to(centerRay.getPoint(500).x,-centerRay.getPoint(500).z,centerRay.getPoint(500).y);

        return mEngine->rayTest2(from,to);
    }
Пример #4
0
	std::pair<std::string, float> PhysicsSystem::getFacedHandle (MWWorld::World& world)
	{
		std::string handle = "";

        //get a ray pointing to the center of the viewport
        Ray centerRay = mRender.getCamera()->getCameraToViewportRay(
        mRender.getViewport()->getWidth()/2,
        mRender.getViewport()->getHeight()/2);
        //let's avoid the capsule shape of the player.
        centerRay.setOrigin(centerRay.getOrigin() + 20*centerRay.getDirection());
        btVector3 from(centerRay.getOrigin().x,-centerRay.getOrigin().z,centerRay.getOrigin().y);
        btVector3 to(centerRay.getPoint(500).x,-centerRay.getPoint(500).z,centerRay.getPoint(500).y);

        return mEngine->rayTest(from,to);
    }
Пример #5
0
	Intersection Quad::intersect(const Ray& ray, float previousBestDistance) const
	{
		float factor= dot(ray.d,qnormal);

		if(factor==0.0) return Intersection::failure();

		float t= dot((qv1-ray.o),qnormal)/factor;

		if (t> previousBestDistance || t<0.0001) return Intersection::failure();

		Point p=ray.getPoint(t);

		/****** n = -det(PA, PQ)/det(PQ, PR)
				m = det(PA, PR)/det(PQ, PR)
				det(PA, PQ) = PA.x*PQ.y-PQ.x*PA.y
		******/
		bool a = dot(cross(qv2 - qv1, p - qv1), qnormal) >= 0;
		bool b = dot(cross(qv4 - qv2, p - qv2), qnormal) >= 0;
		bool c = dot(cross(qv3 - qv4, p - qv4), qnormal) >= 0;
		bool d = dot(cross(qv1 - qv3, p - qv3), qnormal) >= 0;

		if (a && b && c && d)
			return Intersection(t, ray, this, qnormal, p);
		else
			return Intersection::failure();
		/*
		float n = (qspan1.x * ( p.y - qv1.y) - p.x*qspan1.y + qv1.x*qspan1.y) / (qspan2.y * qspan1.x - qspan2.x*qspan1.y);
		if (n < 0 || n > 1) return Intersection::failure();
		float m = (p.x - qv1.x - n *qspan2.x) / qspan1.x;
		if (m < 0 || m > 1) return Intersection::failure(); 
		
		return Intersection(t,ray,this,qnormal,p);
		*/

	}
Пример #6
0
Spectrum Camera::evaluateWe( const Ray &i_ray, glm::vec2* o_rasterPosition ) const
{
    glm::vec3 directionWorld = Transform::transform( glm::vec3( 0.0, 0.0, -1.0 ), m_cameraToWorld );
    float cosTheta = glm::dot( i_ray.getDirection(), directionWorld );
    
    // See if they are pointing in the same direction
    if ( cosTheta <= 0.0f ) {
        return Spectrum::black();
    }
    
    // Find point on plane of focus and convert that to
    // raster coordinates
    float t = ( m_aperature > 0.0f ? m_focalLength : 1.0 ) / cosTheta;
    glm::vec3 focusPoint = i_ray.getPoint( t );
    glm::vec2 rasterPoint = glm::vec2( glm::inverse( m_rasterToCamera ) *
                                       m_worldToCamera *
                                       glm::vec4( focusPoint, 1.0) );
    
    // Optionally return raster position
    if ( o_rasterPosition != nullptr ) {
        *o_rasterPosition = glm::vec2( rasterPoint );
    }
    
    if ( !m_rasterBounds.isInside( rasterPoint ) ) {
        return Spectrum::black();
    }
    
    float lensArea = m_aperature == 0.0f ? 1.0f : ( M_PI * m_aperature * m_aperature );
    float cos2Theta = cosTheta * cosTheta;
    
    return Spectrum( 1.0f / ( m_area * lensArea * cos2Theta * cos2Theta ) );
}
const Vector3 Lambert::shade(const unsigned int threadID, const Ray& ray, const HitInfo &hit, const Scene& scene, bool isSecondary) const
{
    Vector3 L		= Vector3(0.0f, 0.0f, 0.0f);
	Vector3 rayD	= Vector3(ray.d[0],ray.d[1],ray.d[2]);		// Ray direction
	Vector3 viewDir	= -rayD;									// View direction
	float u, v;
	Vector3 N, geoN, T, BT;
	Vector3 diffuseColor = m_kd;

	Vector3 P = ray.getPoint(hit.t);

	hit.getAllInfos(N, geoN, T, BT, u, v);

	if (m_colorMap != NULL) 
	{
		Vector4 texCol = m_colorMap->getLookup(u, v);
		diffuseColor = Vector3(texCol.x, texCol.y, texCol.z);
	}

    const Lights *lightlist = scene.lights();
    
    // loop over all of the lights
    Lights::const_iterator lightIter;
    for (lightIter = lightlist->begin(); lightIter != lightlist->end(); lightIter++)
    {
		float discard;
		Vector3 lightPower = (*lightIter)->sampleLight(threadID, P, N, ray.time, scene, 0, discard);		
		L += lightPower * diffuseColor;								// Calculate Diffuse component
    }
    
    // add the ambient component
    L += m_ka;
    
    return L;
}
Пример #8
0
bool OsgSceneObject::intersectRay(const Ray& ray, Vector3f* hitPoint)
{
	Vector3f rstart = ray.getOrigin();
	
	// Compute reasonable ray length based on distance between ray origin and
	// owner scene node center.
	Vector3f center = getOwner()->getBoundCenter();
	float dir = (ray.getOrigin() - center).norm();
	Vector3f rend = ray.getPoint(dir * 2);

	osg::Vec3d orig(rstart[0], rstart[1], rstart[2]);
	osg::Vec3d end(rend[0], rend[1], rend[2]);


	Ref<osgUtil::LineSegmentIntersector> lsi = new osgUtil::LineSegmentIntersector(orig, end);
	osgUtil::IntersectionVisitor iv(lsi);

	myTransform->accept(iv);

	if(!lsi->containsIntersections()) return false;

	osgUtil::LineSegmentIntersector::Intersection i = lsi->getFirstIntersection();
	
	osg::Vec3d intersect = i.getWorldIntersectPoint();

	hitPoint->x() = intersect[0];
	hitPoint->y() = intersect[1];
	hitPoint->z() = intersect[2];
	return true;
}
Пример #9
0
bool pathDrawerState::mouseMoved(const OIS::MouseEvent& e)
{
    //cout << _nodoSelector->getName().substr(0,_nodoSelector->getName().find("_")) << endl;
    //cout << "mousemove " << _nodoSelector->getName() << endl;
    if (InputManager_::getSingletonPtr()->getMouse()->getMouseState().buttonDown(OIS::MB_Left) &&
        //_nodoSelector && _nodoSelector->getName() != "PlaneRoadBig") //"track1Big")
        _nodoSelector && 
        _nodoSelector->getName().substr(0,_nodoSelector->getName().find("_")-1) != _checkPointInfo.nombreNodo)
    {
        Ray r = setRayQuery(e.state.X.abs, e.state.Y.abs, MASK_CIRCUITO | MASK_MARCA);
        RaySceneQueryResult &result = _raySceneQuery->execute();
        RaySceneQueryResult::iterator it;
        it = result.begin();
        if (it != result.end() && it->movable->getParentSceneNode()->getName() == "PlaneRoadBig") 
        {   
            Vector3 pos = r.getPoint(it->distance);
            pos.y = _planeRoadNode->getPosition().y + 1;
            _nodoSelector->setPosition(pos);
            recolocarLinea();
        }
    }
        
    
    return true;
}
	// ---------------------------------------------------------------------------------
	bool ConvexPolygon::isHitBy(const Ray& ray) const {
		// Create a RayStart->Edge defined plane. 
		// If the intersection of the ray to the polygon's plane is inside for all the planes, it is inside the poly
		// By inside, I mean the point is on positive side of the plane
		std::pair<bool, Real> intersection = ray.intersects(mPlane);
		
		if (!intersection.first) 
			return false;
		
		// intersection point
		Vector3 ip     = ray.getPoint(intersection.second);
		Vector3 origin = ray.getOrigin();
				
		unsigned int pointcount = mPoints.size();
		for (unsigned int idx = 0; idx < pointcount; idx++) {
			int iv2 = (idx + 1) % pointcount;
			
			Vector3 v1 = mPoints[idx];
			Vector3 v2 = mPoints[iv2];
			
			Plane frp(origin, v1, v2);
			
			// test whether the intersection is inside
			if (frp.getSide(ip) != Plane::POSITIVE_SIDE)
				return false;
		}
		
		return true;
	}
Пример #11
0
LRESULT Canvas::OnLeftButtonDown( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled )
{
	//
	int x = GET_X_LPARAM(lParam);
	int y = GET_Y_LPARAM(lParam);
	//_cameraController.onLeftButtonDown(x,y);

	bHandled = false;
	
	//拾取射线
	Ray r = _camera.getCameraToViewportRay(x, y);
	
	//与xz平面的交点
	Real t = -r._origin.y / r._direction.y;
	Vec3 p = r.getPoint(t);
	Vec3 ap = _getActorPosition();
	p -= ap;
	Real len = p.length();
	_positionSpeed = 0.010f / len;
	//目标点
	_setActorPosition(p);
	
	//调整主角方向
	Quaternion q;
	Radian angle = Euler::Basic::ATan2(p.x, p.z);
	q.FromAngleAxis(angle, Vec3::UNIT_Y);
	_angleSpeed = 0.01f;
	_setActorAngle(q);
	return 0;
}
Пример #12
0
// this is called at simulation time
void DemoApplication::UpdateMousePick ()
{
	bool mouseKey1 = m_mouseState.buttonDown(OIS::MB_Left);

	OgreNewtonRayPickManager* const rayPicker = m_physicsWorld->GetRayPickManager();
	if (m_keyboard->isKeyDown(OIS::KC_LCONTROL) || m_keyboard->isKeyDown(OIS::KC_RCONTROL)) {
		m_cursor->setVisible(true);
		if (mouseKey1) {
			Real mx = Real (m_mouseState.X.abs) / Real(m_mouseState.width);
			Real my = Real (m_mouseState.Y.abs) / Real(m_mouseState.height);
			Ray camray (mCamera->getCameraToViewportRay(mx, my));

			Vector3 start (camray.getOrigin());
			Vector3 end (camray.getPoint (200.0f));

			if (!m_mousePickMemory) {
				rayPicker->SetPickedBody (NULL);
				dNewtonBody* const body = rayPicker->RayCast (start, end, m_pickParam);
				if (body) {
					rayPicker->SetPickedBody (body, start + (end - start) * m_pickParam);
				}
			} else {
				rayPicker->SetTarget (start + (end - start) * m_pickParam);
			}

		} else {
			rayPicker->SetPickedBody (NULL);
		}
	} else {
		m_cursor->setVisible(false);
		rayPicker->SetPickedBody (NULL);
	}
	m_mousePickMemory = mouseKey1;
}
Пример #13
0
IntersectResult Sphere::intersect(Ray &ray)
{ 
    IntersectResult result(false);

    // Solve:
    //   | (o + t * dir) - c | = radius
    //  ==> ( co + t * dir ) ^ 2 - radius ^ 2 = 0
    //  ==> dir * dir * t ^ 2 + 2 * dir.co * t + (co.co - radius * radius) = 0
    //  ==> t ^ 2 + (2 * dir.co) * t + (co.co - radius * radius) = 0
    //  ==> t = - dir.co +- sqr((dir.co * dir.co) - (co.co - radius * radius))
    Vector co = Vector(center, ray.origin);
    double b = ray.direction.dot(co);
    double delta = b * b - (co.dot(co) - radius * radius);

    if (delta >= 0)
    {
        delta = sqrt(delta);
        if (-b + delta >= 0.0005f)
        {
            result.hit = true;
            result.geometry = this;
            //result.distance = (-b - delta >= 0.0005f) ? -b - delta : -b + delta;
            result.distance = -b; // in the SBR algorithm, there should be only one intersection
            result.position = ray.getPoint(result.distance);
            result.normal = Vector(center, result.position).norm();
        }
    }
    return result;
}
Пример #14
0
void Global::updatePickingPoint_()
{
    Ray r = getRenderContex()->getPickingRay();
    float x, z;
    if (0)
    {
        //对于平面地表,可以这样处理
        float t = -r.origion_.y / r.direction_.y;
        x = r.origion_.x + t * r.direction_.x;
        z = r.origion_.z + t * r.direction_.z;
    }
    else
    {
        sPick pk;
        pk.empty_ = true;
        calcPick(pk, r, getSceneManager()->getTerrainQuadTreeRoot());
        if (pk.empty_)
        {
            return;
        }
        Vector3 p = r.getPoint(pk.ps_.z);
        p = (1 - pk.ps_.x - pk.ps_.y)*pk.p0_ + pk.ps_.x*pk.p1_ + pk.ps_.y*pk.p2_;
        x = p.x;
        z = p.z;
    }

    if (getSceneManager()->getTerrain())
    {
        getSceneManager()->getTerrain()->updateVisibleChunks(x, z);
    }
    if (getGlobal() && getGlobal()->getBrushDecal())
    {
        getGlobal()->getBrushDecal()->setCenter(Vector4(x, 0, z, 1));
    }
}
Пример #15
0
	// Dibujado de raycast para depurar
	void CShootRaycast::drawRaycast(const Ray& raycast) {
		Graphics::CScene *scene = Graphics::CServer::getSingletonPtr()->getActiveScene();
		Ogre::SceneManager *mSceneMgr = scene->getSceneMgr();

		std::stringstream aux;
		aux << "laser" << _nameWeapon << _temporal;
		++_temporal;
		std::string laser = aux.str();

		Ogre::ManualObject* myManualObject =  mSceneMgr->createManualObject(laser); 
		Ogre::SceneNode* myManualObjectNode = mSceneMgr->getRootSceneNode()->createChildSceneNode(laser+"_node"); 
 
		myManualObject->begin("laser", Ogre::RenderOperation::OT_LINE_STRIP);
		Vector3 v = raycast.getOrigin();
		myManualObject->position(v.x,v.y,v.z);

		for(int i=0; i < _distance;++i){
			Vector3 v = raycast.getPoint(i);
			myManualObject->position(v.x,v.y,v.z);
			// etc 
		}

		myManualObject->end(); 
		myManualObjectNode->attachObject(myManualObject);
	}// drawRaycast
bool TutorialApplication::mouseMoved(const OIS::MouseEvent &arg)
{
    auto ret = BaseApplication::mouseMoved(arg);
//    std::cout << "moust at ("
//              << arg.state.X.abs << ","
//              << arg.state.Y.abs << ","
//              << arg.state.Z.abs << ")" << std::endl;
//    std::cout << "plane at Y = " << m_activeLevel.d << std::endl;

    Ray mouseRay = getMouseRay();

    if (m_verticalMode) {
        // ignored for now, untill I figure out how to make it intuitive
    } else {
        auto r = mouseRay.intersects(m_activeLevel);
        if (r.first) {
            auto pos = mouseRay.getPoint(r.second);
            auto gridPos =
                    Vector3(floor(pos.x / GRID_SPACING) * GRID_SPACING,
                            pos.y,
                            floor(pos.z / GRID_SPACING) * GRID_SPACING);
            m_cursorNode->setPosition(gridPos);
            auto pointPos =
                    Vector3(round(pos.x / GRID_SPACING) * GRID_SPACING,
                            pos.y,
                            round(pos.z / GRID_SPACING) * GRID_SPACING);
            m_pointNode->setPosition(pointPos);

            if (m_mode == WitchMode) {
                for (std::size_t i = 0; i < CONE_CASES.size(); i++) {
                    auto c = CONE_CASES[i];
                    bool containsCreatures = true;
                    for (Vector3 creature : m_ogres) {
                        Vector3 dir = creature - gridPos;

                        // cone is facing wrong way for creature
                        if (dir.angleBetween(c) > Degree(45)) {
                            containsCreatures = false;
                            break;
                        }

                        // creature too far away for cone
                        if (distance3(dir.x, dir.y, dir.z) > CONE_SIZE) {
                            containsCreatures = false;
                        }
                    }

                    if (containsCreatures) {
                        m_coneNodes[i]->setVisible(true);
                    } else {
                        m_coneNodes[i]->setVisible(false);
                    }
                }
            }
        }
    }
    return ret;
}
Пример #17
0
void GlyphFace::_fullIntersect(const Ray& world_ray, const double world_t, Intersection& result) const {
    Ray ray = rayToObject(world_ray);
    double t = world_t*ray.t_scale;
    
    Vector p = ray.getPoint(t);
    Vector2 uv; // No support for UV-coordinates
    result = Intersection(p,t,normal,uv);
    intersectionToWorld(result);
}
Пример #18
0
// ray r1 started at time t1 minus ray r2 started at time t2
Ray			rayMinusRay(const Ray& r1, float t1,
					const Ray& r2, float t2)
{
  // get points at respective times
  float p1[3], p2[3];
  r1.getPoint(t1, p1);
  r2.getPoint(t2, p2);

  // construct new ray
  float p[3], d[3];
  p[0] = p1[0] - p2[0];
  p[1] = p1[1] - p2[1];
  p[2] = p1[2] - p2[2];
  d[0] = r1.getDirection()[0] - r2.getDirection()[0];
  d[1] = r1.getDirection()[1] - r2.getDirection()[1];
  d[2] = r1.getDirection()[2] - r2.getDirection()[2];
  return Ray(p, d);
}
Пример #19
0
void Sphere::_fullIntersect(const Ray& ray, const double t, Intersection& result) const {
    Vector p = ray.getPoint(t);
    Vector n = p - center;
    n.normalize();
    Vector2 uv;
    if (getMaterial() != NULL && getMaterial()->requiresUV()) {
	//cout << "Getting UV" << endl;
	uv = getUV(n);
    } 
    result = Intersection(p,t,n,uv);
}
Пример #20
0
    std::vector < std::pair <float, std::string> > PhysicsSystem::getFacedObjects (float mouseX, float mouseY)
    {
        Ray ray = mRender.getCamera()->getCameraToViewportRay(mouseX, mouseY);
        Ogre::Vector3 from = ray.getOrigin();
        Ogre::Vector3 to = ray.getPoint(500); /// \todo make this distance (ray length) configurable

        btVector3 _from, _to;
        // OGRE to MW coordinates
        _from = btVector3(from.x, -from.z, from.y);
        _to = btVector3(to.x, -to.z, to.y);

        return mEngine->rayTest2(_from,_to);
    }
Пример #21
0
//intersect
Intersection InfinitePlane::intersect(const Ray& ray, float previousBestDistance) const
{
	float x = dot(ray.d_, normal_);

	if (std::abs(x)<epsilon)
	{
		return Intersection::failure();
	}

	float distance = (dot(Vector(origin_.x_, origin_.y_, origin_.z_), normal_) - dot(Vector(ray.o_.x_, ray.o_.y_, ray.o_.z_), normal_)) / x;

	return Intersection(distance, ray, this, normal_, ray.getPoint(distance), true);
}
bool CubeCollider::raycastALT(const Ray & ray, RaycastHit & hitInfo){

	glm::vec3 position = object->getTransform()->getPosition();
	glm::vec3 dirToCenter = ray.origin - position;
	if(glm::dot(ray.direction, dirToCenter) >= 0){
		//std::cout << "ray is going in a different direction" << std::endl;
		return false;
	}

	transformNormals();

	Plane planes[6];
	for(int i = 0; i < 6; i ++){
		planes[i] = Plane(transformedNormals[i],position + center + (transformedNormals[i] * size * .5f) );
	}

	for(int i = 0; i < 6; i ++){
		bool viable = true;
		Plane plane = planes[i];
		float enter;
		if(plane.raycast(ray, enter)){
			glm::vec3 point = ray.getPoint(enter);
			for(int j = 0; j < 6; j++){
				if(i == j) continue;

				if(glm::dot(planes[i].normal, point - planes[i].point ) >= 0){
					//point is behind plane
				}
				else{
					//point is in front of plane
					viable = false;
					break;
				}
			}
			if(viable){
				hitInfo.point = point;
				hitInfo.distance = enter;
				hitInfo.normal = transformedNormals[i];
				hitInfo.object = object;
				return true;
			}
		}
		else{
			// a ray missed one of the faces
			return false;
		}


	}
	return false;
}
Пример #23
0
void ExtrudedCurve::_fullIntersect(const Ray& world_ray, const double world_t, Intersection& result) const {
    Ray ray = rayToObject(world_ray);
    double t = world_t*ray.t_scale;
    
    Vector p = ray.getPoint(t);
    Vector2 along = b(findClosestT(ray) + EPSILON);
    Vector p2 = p - Vector(along.x(), along.y(), p.z());
    Vector p3 = p - Vector(p.x(), p.y(), p.z() - EPSILON);
    Vector n = Vector::xProduct(p3,p2);
    n.normalize();
    Vector2 uv; // No support for UV-coordinates
    result = Intersection(p,t,n,uv);
    intersectionToWorld(result);
}
Пример #24
0
bool Bullet::raycast(const Ray& ray, PhysicsIntersectResult& result) const
{
    auto endPoint = ray.getPoint(MaxRayDistance);

    auto intersections = Vector<PhysicsIntersectResult>();
    auto callback = RayResultCollector(ray, intersections);
    dynamicsWorld_->rayTest(toBullet(ray.getOrigin()), toBullet(endPoint), callback);

    if (intersections.empty())
        return false;

    intersections.sort();
    result = intersections[0];

    return true;
}
Пример #25
0
Intersection InfinitePlane::intersect(const Ray& ray, float previousBestDistance) const
{
    float temp = dot(ray.d , normal);
    float distance = dot((origin - ray.o), normal) / temp;
    Point hit = ray.getPoint(distance);
    Point local = Point(hit.x - origin.x, hit.y - origin.y, hit.z - origin.z);
    if(distance > epsilon && distance + epsilon < previousBestDistance) {
        float dir = dot(ray.o - origin, normal);
        if(dir < 0) {
            return Intersection(distance, ray, this, -normal, local);
        } else if(dir > 0) {
            return Intersection(distance, ray, this, normal, local);
        }
    }
    return Intersection::failure();
}
Пример #26
0
double GlyphFace::_fastIntersect(const Ray& world_ray) const {
    Ray ray = rayToObject(world_ray);
    Vector d = ray.getDirection();
    Vector o = ray.getOrigin();
    
    // Find the point p where the ray intersects the xy-plane
    if (d.z() == 0) return -1;
    double t = -o.z() / d.z();
    if (t < EPSILON) return -1;
    
    Vector pp = ray.getPoint(t);
    Vector2 p = Vector2(pp.x(), pp.y());
    
    // Make sure that the intersection point p is inside the glyph.
    if (!glyph->isInside(p)) return -1;
    
    // Return the t in world scale
    return t / ray.t_scale;
}
Пример #27
0
Real Chunks::getHeight( Real x, Real z )
{
	Real height = 0.0f;
	//遍历顶点,筛选出地形圆覆盖的顶点
	for (size_t i = 0; i != mChunks.size(); ++i)
	{
		Chunk* c = mChunks[i];
		//先过滤大部分的chunk
		{
			//如何判断一个点是否在一个正方形?
			Vec3 leftLow = mPosition + Vec3(scChunkSize * c->mPostion.x, 0.0f, -scChunkSize * c->mPostion.y);
			Real maxX = leftLow.x + scChunkSize;
			Real minX = leftLow.x;
			Real maxZ = leftLow.z;
			Real minZ = leftLow.z - scChunkSize;
			if (x < minX || x > maxX || z < minZ || z > maxZ)
			{
				continue;
			}
		}
		Mat4 m;
		m.makeTransform(mPosition + Vec3(scChunkSize * c->mPostion.x, 0.0f, -scChunkSize * c->mPostion.y), Vec3(scChunkSize, 1.0f, scChunkSize), Quaternion::IDENTITY);
		std::vector<Real> ts;
		Vec3 p = Vec3(x, 0.0f, z);
		Ray r;
		r._direction = Vec3::NEGATIVE_UNIT_Y;
		r._origin = Vec3(x, 100000.0f, z);
		for (size_t k = 0; k != c->mIndices.size(); k += 3)
		{
			Vec3 p0 = m * c->mVertices[c->mIndices[k]];
			Vec3 p1 = m * c->mVertices[c->mIndices[k + 1]];
			Vec3 p2 = m * c->mVertices[c->mIndices[k + 2]];
			std::pair<bool, Real> result = Zen::intersects(r, p0, p1, p2);
			if (result.first)
			{
				height = r.getPoint(result.second).y;
				return height;
			}
		}
	}
	return height;
}
Пример #28
0
Color Object::phongReflectionColor(const Ray &ray, const Point &P, Scene* scene) const {

	Object* tempObject;
	Point tempPoint;
	double L_N, R_V_alpha;

	Vector N = normalAtPoint(P), L, R;
	Vector V = Vector(P, ray.getPoint()).normalize();

	Color ambiant = scene->getAmbiantColor(), lightColor;

	double red = Ka[0] * ambiant.R,
    green = Ka[1] * ambiant.G,
    blue  = Ka[2] * ambiant.B;

    std::vector<Light*>::const_iterator l;

	for (l = scene->lightsBegin(); l != scene->lightsEnd(); ++l) {

		L = Vector(P, (*l)->getSource()).normalize();
		if (L * N < 0)
			continue;
		scene->firstObjectHitByRay(Ray((*l)->getSource(), L * (-1)), tempObject,
				tempPoint);
		if (tempObject != this)
			continue;

		lightColor = (*l)->getColor();
		R = L.reflectedBy(N);

		L_N = L * N;
		R_V_alpha = pow(R * V, alpha);

		red   += lightColor.R * (Kd[0] * L_N + Ks[0] * R_V_alpha);
		green += lightColor.G * (Kd[1] * L_N + Ks[1] * R_V_alpha);
		blue  += lightColor.B * (Kd[2] * L_N + Ks[2] * R_V_alpha);
	}

	return Color((unsigned char)((red > 255) ? 255 : red),
                 (unsigned char)((green > 255) ? 255 : green),
		         (unsigned char)((blue > 255) ? 255 : blue));
}
Пример #29
0
void SceneMouse::update(float dt)
{
    if (App::sim_state.GetActive() == SimState::PAUSED) { return; } // Do nothing when paused

    if (mouseGrabState == 1 && grab_truck)
    {
        // get values
        Ray mouseRay = getMouseRay();
        lastgrabpos = mouseRay.getPoint(mindist);

        // update visual line
        pickLine->beginUpdate(0);
        pickLine->position(grab_truck->nodes[minnode].AbsPosition);
        pickLine->position(lastgrabpos);
        pickLine->end();

        // add forces
        grab_truck->mouseMove(minnode, lastgrabpos, mouseGrabForce);
    }
}
Пример #30
0
  std::pair<bool, Vector3> TerrainInfo::rayIntersects(const Ray& ray) const
  {
    AxisAlignedBox box = getExtents();
    Vector3 point = ray.getOrigin();
    Vector3 dir = ray.getDirection();

    // first, does the ray start from inside the terrain extents?
    if (!box.contains(point))
    {
      // not inside the box, so let's see if we are actually
      // colliding with it
      pair<bool, Real> res = ray.intersects(box);
      if (!res.first)
        return make_pair(false, Vector3::ZERO);
      // update point to the collision position
      point = ray.getPoint(res.second);
    }

    // now move along the ray until we intersect or leave the bounding box
    while (true)
    {
      // have we arived at or under the terrain height?
      // note that this approach means that ray queries from below won't work
      // correctly, but then again, that shouldn't be a usual case...
      float height = getHeightAt(point.x, point.z);
      if (point.y <= height)
      {
        point.y = height;
        return make_pair(true, point);
      }

      // move further...
      point += dir;

      // check if we are still inside the boundaries
      if (point.x < box.getMinimum().x || point.z < box.getMinimum().z
        || point.x > box.getMaximum().x || point.z > box.getMaximum().z)
        return make_pair(false, Vector3::ZERO);

    }
  }