Exemplo n.º 1
0
    void ArMoveProperty::UpdateRotation(ArGameEntity* srcEntity, const DiK2Pos& targetPos, float dt, int turnRate)
    {
        DiK2RenderObject* renderObj = srcEntity->GetRenderObj();
        auto newPos = renderObj->GetPosition();

        DiVec3 direction = DiVec3(targetPos.x, 0, targetPos.z) - DiVec3(newPos.x, 0, newPos.z);
        direction.y = 0;
        direction.normalise();
        float yawToGoal;
        DiVec3 srcVec = renderObj->GetRotQuat() * DiVec3::UNIT_Z;

        if ((1.0f + srcVec.dotProduct(direction)) < 0.0001f)
            yawToGoal = 180;
        else
        {
            DiQuat toGoal = renderObj->GetRotQuat().zAxis().getRotationTo(direction);
            yawToGoal = toGoal.getYaw().valueDegrees();
        }

        float yawAtSpeed = yawToGoal / DiMath::Abs(yawToGoal) * dt * ((float)turnRate);
        if (yawToGoal < 0)
            yawToGoal = std::min<float>(0, std::max<float>(yawToGoal, yawAtSpeed));
        else if (yawToGoal > 0)
            yawToGoal = std::max<float>(0, std::min<float>(yawToGoal, yawAtSpeed));

        DiQuat actorOrientation = renderObj->GetRotQuat();
        actorOrientation = DiQuat(DiDegree(yawToGoal), DiVec3::UNIT_Y) * actorOrientation;

        float rotrad = actorOrientation.getYaw().valueRadians();
        renderObj->SetRotation(rotrad);
    }
Exemplo n.º 2
0
    void DiInstanceBatch::DefragmentBatchDoCull( InstancedModelVec &usedEntities )
    {
        auto itor = usedEntities.begin();
        auto end = usedEntities.end();

        DiVec3 vMinPos = DiVec3::ZERO, firstPos = DiVec3::ZERO;
        DiInstancedModelPtr first;

        if( !usedEntities.empty() )
        {
            first    = *usedEntities.begin();
            firstPos= first->GetDerivedPosition();
            vMinPos = first->GetDerivedPosition();
        }

        while( itor != end )
        {
            const DiVec3 &vPos = (*itor)->GetDerivedPosition();

            vMinPos.x = DiMath::Min( vMinPos.x, vPos.x );
            vMinPos.y = DiMath::Min( vMinPos.y, vPos.y );
            vMinPos.z = DiMath::Min( vMinPos.z, vPos.z );
            if( vMinPos.squaredDistance( vPos ) < vMinPos.squaredDistance( firstPos ) )
            {
                firstPos = vPos;
            }
            ++itor;
        }

        while( !usedEntities.empty() && mInstancedModels.size() < mInstancesPerBatch )
        {
            auto closest = usedEntities.begin();
            auto it = usedEntities.begin();
            auto e = usedEntities.end();

            DiVec3 closestPos;
            closestPos = (*closest)->GetDerivedPosition();

            while( it != e )
            {
                const DiVec3 &vPos = (*it)->GetDerivedPosition();
                if( firstPos.squaredDistance( vPos ) < firstPos.squaredDistance( closestPos ) )
                {
                    closest      = it;
                    closestPos   = vPos;
                }
                ++it;
            }

            mInstancedModels.push_back( *closest );

            *closest = *(usedEntities.end() - 1);
            usedEntities.pop_back();
        }
    }
Exemplo n.º 3
0
 inline void DiGravityController::Control(DiParticleElement* particleTechnique, DiParticle* particle, float timeElapsed)
 {
     DiVec3 distance = mDerivedPosition - particle->position;
     float length = distance.squaredLength();
     
     float scaleVelocity = 1.0f;
     if (mParentElement)
         scaleVelocity = mParentElement->GetParticleSystemScaleVelocity();
     
     if (length > 0 && mParentElement)
     {
         //float force = (mGravity * particle->mass * mass) / length;
         float force = (scaleVelocity * mGravity * particle->mass * mass) / length;
         particle->direction += force * distance * timeElapsed * CalculateAffectSpecialisationFactor(particle);
     }
 }
Exemplo n.º 4
0
	DiMat4 DiFocusedShadowPolicy::buildViewMatrix(const DiVec3& pos, const DiVec3& dir, 
		const DiVec3& up) const
	{
		DiVec3 xN = dir.crossProduct(up);
		xN.normalise();
		DiVec3 upN = xN.crossProduct(dir);
		upN.normalise();

		DiMat4 m(xN.x,		xN.y,		xN.z,		-xN.dotProduct(pos),
			upN.x,		upN.y,		upN.z,		-upN.dotProduct(pos),
			-dir.x,		-dir.y,	-dir.z,	dir.dotProduct(pos),
			0.0,			0.0,		0.0,		1.0
			);

		return m;
	}
Exemplo n.º 5
0
    void DiNormalShadowPolicy::getShadowCamera (const DiSceneManager *sm, const DiCamera *cam,
                                                    const DiViewport *vp, const DiLight *light, DiCamera *texCam, size_t iteration) const
	{
		DiVec3 pos, dir;
        
		// reset custom view / projection matrix in case already set
		texCam->SetCustomViewMatrix(false);
		texCam->SetCustomProjectionMatrix(false);
		texCam->SetNearClipDistance(light->DeriveShadowNearClipDistance(cam));
		texCam->SetFarClipDistance(light->DeriveShadowFarClipDistance(cam));
        
		// get the shadow frustum's far distance
		float shadowDist = sm->GetShadowFarDistance();
		if (!shadowDist)
		{
			// need a shadow distance, make one up
			shadowDist = cam->GetNearClipDistance() * 300;
		}
		float shadowOffset = shadowDist * (sm->GetShadowDirLightTextureOffset());
        
		// Directional lights
		if (light->GetType() == LIGHT_DIRECTIONAL)
		{
			// set up the shadow texture
			// Set ortho projection
			texCam->SetProjectionType(PT_ORTHOGRAPHIC);
			// set ortho window so that texture covers far dist
			texCam->SetOrthoWindow(shadowDist * 2, shadowDist * 2);
            
			// Calculate look at position
			// We want to look at a spot shadowOffset away from near plane
			// 0.5 is a litle too close for angles
			DiVec3 target = cam->GetDerivedPosition() +
            (cam->GetDerivedDirection() * shadowOffset);
            
			// Calculate direction, which same as directional light direction
			dir = - light->GetDerivedDirection(); // backwards since point down -z
			dir.normalise();
            
			// Calculate position
			// We want to be in the -ve direction of the light direction
			// far enough to project for the dir light extrusion distance
			pos = target + dir * sm->GetShadowDirLightExtrusionDistance();
            
			float worldTexelSize = (shadowDist * 2) / (vp->mWidth * vp->mParent->GetWidth());
            
            //get texCam orientation
            
            DiVec3 up = DiVec3::UNIT_Y;
            // Check it's not coincident with dir
            if (DiMath::Abs(up.dotProduct(dir)) >= 1.0f)
            {
				// Use camera up
				up = DiVec3::UNIT_Z;
            }
            // cross twice to rederive, only direction is unaltered
            DiVec3 left = dir.crossProduct(up);
            left.normalise();
            up = dir.crossProduct(left);
            up.normalise();
            // Derive quaternion from axes
            DiQuat q;
            q.FromAxes(left, up, dir);
            
            //convert world space camera position into light space
            DiVec3 lightSpacePos = q.Inverse() * pos;
            
            //snap to nearest texel
            lightSpacePos.x -= fmod(lightSpacePos.x, worldTexelSize);
            lightSpacePos.y -= fmod(lightSpacePos.y, worldTexelSize);
            
            //convert back to world space
            pos = q * lightSpacePos;
			
		}
        else if (light->GetType() == LIGHT_SPOT)
        {
            const DiSpotLight* spot = static_cast<const DiSpotLight*>(light);
            
            // Set perspective projection
			texCam->SetProjectionType(PT_PERSPECTIVE);
			// set FOV slightly larger than the spotlight range to ensure coverage
			DiRadian fovy = spot->GetOuterAngle() * 1.2;
			// limit angle
			if (fovy.valueDegrees() > 175)
				fovy = DiDegree(175);
			texCam->SetFOVy(fovy);
            
			// Calculate position, which same as spotlight position
			pos = light->GetDerivedPosition();
            
			// Calculate direction, which same as spotlight direction
			dir = - light->GetDerivedDirection(); // backwards since point down -z
			dir.normalise();
        }
		else
        {
            DI_ASSERT_FAIL;
        }
        
		// Finally set position
		texCam->SetPosition(pos);
        
		DiVec3 up = DiVec3::UNIT_Y;
		// Check it's not coincident with dir
		if (DiMath::Abs(up.dotProduct(dir)) >= 1.0f)
		{
			// Use camera up
			up = DiVec3::UNIT_Z;
		}
		// cross twice to rederive, only direction is unaltered
		DiVec3 left = dir.crossProduct(up);
		left.normalise();
		up = dir.crossProduct(left);
		up.normalise();
		// Derive quaternion from axes
		DiQuat q;
		q.FromAxes(left, up, dir);
		texCam->SetOrientation(q);
	}
Exemplo n.º 6
0
	void DiFocusedShadowPolicy::calculateShadowMappingMatrix(const DiSceneManager& sm,
		const DiCamera& cam, const DiLight& light, DiMat4 *out_view, DiMat4 *out_proj, 
		DiCamera *out_cam) const
	{
        DiVec3 lightPos = light.GetDerivedPosition();
        DiVec3 lightDir = light.GetDerivedDirection();
        
		// get the shadow frustum's far distance
		float shadowDist = sm.GetShadowFarDistance();
		if (!shadowDist)
		{
			// need a shadow distance, make one up
			shadowDist = cam.GetNearClipDistance() * 3000;
		}
		float shadowOffset = shadowDist * sm.GetShadowDirLightTextureOffset();

		if (light.GetType() == LIGHT_DIRECTIONAL)
		{
			// generate view matrix if requested
			if (out_view != NULL)
			{
				DiVec3 pos;
#if 0
				if (sm.getCameraRelativeRendering())
				{
					pos = DiVec3::ZERO;
				}
				else
#endif
				{
					pos = cam.GetDerivedPosition();
				}
				*out_view = buildViewMatrix(pos, 
					lightDir,
					cam.GetDerivedUp());
			}

			// generate projection matrix if requested
			if (out_proj != NULL)
			{
				*out_proj = DiMat4::getScale(1, 1, -1);
				//*out_proj = DiMat4::IDENTITY;
			}

			// set up camera if requested
			if (out_cam != NULL)
			{
				out_cam->SetProjectionType(PT_ORTHOGRAPHIC);
				out_cam->SetDirection(lightDir);
				out_cam->SetPosition(cam.GetDerivedPosition());
				out_cam->SetFOVy(DiDegree(90));
				out_cam->SetNearClipDistance(shadowOffset);
			}
		}
        else if (light.GetType() == LIGHT_SPOT)
        {
            const DiSpotLight* spot = static_cast<const DiSpotLight*>(&light);
            // generate view matrix if requested
			if (out_view != NULL)
			{
				*out_view = buildViewMatrix(light.GetDerivedPosition(),
                                            light.GetDerivedDirection(),
                                            cam.GetDerivedUp());
			}
            
			// generate projection matrix if requested
			if (out_proj != NULL)
			{
				// set FOV slightly larger than spotlight range
				mTempFrustum->SetFOVy(DiMath::Clamp<DiRadian>(spot->GetOuterAngle() * 1.2, DiRadian(0), DiRadian(DiMath::PI/2.0f)));
                
				mTempFrustum->SetNearClipDistance(light.DeriveShadowNearClipDistance(&cam));
				mTempFrustum->SetFarClipDistance(light.DeriveShadowFarClipDistance(&cam));
                
				*out_proj = mTempFrustum->GetProjectionMatrix();
			}
            
			// set up camera if requested
			if (out_cam != NULL)
			{
				out_cam->SetProjectionType(PT_PERSPECTIVE);
				out_cam->SetDirection(light.GetDerivedDirection());
				out_cam->SetPosition(light.GetDerivedPosition());
				out_cam->SetFOVy(DiMath::Clamp<DiRadian>(spot->GetOuterAngle() * 1.2, DiRadian(0), DiRadian(DiMath::PI/2.0f)));
				out_cam->SetNearClipDistance(light.DeriveShadowNearClipDistance(&cam));
				out_cam->SetFarClipDistance(light.DeriveShadowFarClipDistance(&cam));
			}
        }
#if 0
		else if (light.GetType() == LIGHT_POINT)
		{
			// target analogue to the default shadow textures
			// Calculate look at position
			// We want to look at a spot shadowOffset away from near plane
			// 0.5 is a little too close for angles
			DiVec3 target = cam.GetDerivedPosition() +
				(cam.GetDerivedDirection() * shadowOffset);
			lightDir = target - lightPos;
			lightDir.normalise();

			// generate view matrix if requested
			if (out_view != NULL)
			{
				*out_view = buildViewMatrix(lightPos,
					lightDir, 
					cam.GetDerivedUp());
			}

			// generate projection matrix if requested
			if (out_proj)
			{
				// set FOV to 120 degrees
				mTempFrustum->SetFOVy(DiDegree(120));

				mTempFrustum->SetNearClipDistance(light._deriveShadowNearClipDistance(&cam));
				mTempFrustum->SetFarClipDistance(light._deriveShadowFarClipDistance(&cam));

				*out_proj = mTempFrustum->GetProjectionMatrix();
			}

			// set up camera if requested
			if (out_cam)
			{
				out_cam->SetProjectionType(PT_PERSPECTIVE);
				out_cam->SetDirection(lightDir);
				out_cam->SetPosition(lightPos);
				out_cam->SetFOVy(DiDegree(120));
				out_cam->SetNearClipDistance(light._deriveShadowNearClipDistance(&cam));
				out_cam->SetFarClipDistance(light._deriveShadowFarClipDistance(&cam));
			}
		}
#endif
    }
Exemplo n.º 7
0
 //-----------------------------------------------------------------------
 void DiPlane::redefine(const DiVec3& rkNormal, const DiVec3& rkPoint)
 {
     normal = rkNormal;
     d = -rkNormal.dotProduct(rkPoint);
 }
Exemplo n.º 8
0
    bool DiCameraHelper::Update( float elapsed )
    {
        if (!mEnabled)
        {
            return false;
        }

        if (mStyle == CS_FREELOOK)
        {
            DiVec3 accel = DiVec3::ZERO;
            if (mGoingForward) 
            {
                accel += mCamera->GetDirection();
            }
            if (mGoingBack)    accel -= mCamera->GetDirection();
            if (mGoingRight)    accel += mCamera->GetRight();
            if (mGoingLeft)    accel -= mCamera->GetRight();
            if (mGoingUp)        accel += mCamera->GetUp();
            if (mGoingDown)    accel -= mCamera->GetUp();

            float topSpeed = mFastMove ? mTopSpeed * 20 : mTopSpeed;
            if (accel.squaredLength() != 0)
            {
                accel.normalise();
                mVelocity += accel * topSpeed * elapsed * 10;
            }
            else 
            {
                mVelocity -= mVelocity * elapsed * 10;
            }

            float tooSmall = std::numeric_limits<float>::epsilon();

            if (mVelocity.squaredLength() > topSpeed * topSpeed)
            {
                mVelocity.normalise();
                mVelocity *= topSpeed;
            }
            else if (mVelocity.squaredLength() < tooSmall * tooSmall)
            {
                mVelocity = DiVec3::ZERO;
            }

            if (mVelocity != DiVec3::ZERO) 
            {
                mCamera->Move(mVelocity * elapsed);
            }
        }
        else if (mStyle == CS_SMOOTH)
        {
            if (Driver && mMousePos.x >= 0 && mMousePos.y >= 0)
            {
                DiRenderWindow* window = Driver->GetMainRenderWindow();
                int x = (mMousePos.x - window->GetWidth() / 2);
                int y = (mMousePos.y - window->GetHeight() / 2);
                DiVec3 pos = mCamera->GetPosition();
                pos.x += (x - pos.x) * 0.01f;
                pos.y += (-y - pos.y) * 0.01f;
                mCamera->SetPosition(pos);
                mCamera->LookAt(0, 0, 0);
            }
        }

        return true;
    }
Exemplo n.º 9
0
 void DiSerializer::ReadObject( DiDataStreamPtr& stream, DiVec3& pDest )
 {
     ReadFloats(stream, pDest.ptr(), 3);
 }
Exemplo n.º 10
0
 void DiSerializer::WriteObject( const DiVec3& vec )
 {
     WriteFloats(vec.ptr(), 3);
 }