示例#1
0
	//----------------------------------------------------------------------------
	void ProcessInputData()
	{
		if (mOverridingCamera){
			mOverridingCamera->ProcessInputData();
			return;
		}
		auto target = mTarget.lock();
		if (!mProcessInput || !mCurrentCamera || !target)
			return;
		if (mUserParams.Changed() || mPrevTargetPos != target->GetPosition())
		{
			mInternalParams.dist += mUserParams.dDist;
			mInternalParams.dist = std::max((Real)2.0f, (Real)mInternalParams.dist);
			if (mInternalParams.dist > 300.0)
				mInternalParams.dist = 300.0;

			mInternalParams.pitch += mUserParams.dPitch;
			if (mInternalParams.pitch > fb::HALF_PI - fb::Radian(5))
			{
				mInternalParams.pitch = fb::HALF_PI - fb::Radian(5);
			}
			else if (mInternalParams.pitch <  -fb::HALF_PI + fb::Radian(5))
			{
				mInternalParams.pitch = -fb::HALF_PI + fb::Radian(5);
			}

			mInternalParams.yaw += mUserParams.dYaw;
			if (mInternalParams.yaw > fb::TWO_PI)
			{
				mInternalParams.yaw -= fb::TWO_PI;
			}
			else if (mInternalParams.yaw < -fb::TWO_PI)
			{
				mInternalParams.yaw += fb::TWO_PI;
			}

			Vec3 defaultDir = -Vec3::UNIT_Y;
			Quat qPitch(mInternalParams.pitch, Vec3::UNIT_X);
			Quat qYaw(-mInternalParams.yaw, Vec3::UNIT_Z);
			Vec3 toCam = qPitch * defaultDir;
			toCam = qYaw * toCam;
			Vec3 forward = -toCam;
			Vec3 right = forward.Cross(Vec3::UNIT_Z);
			right.Normalize();
			Vec3 up = right.Cross(forward);
			forward = up.Cross(right);

			Mat33 rot(right.x, forward.x, up.x,
				right.y, forward.y, up.y,
				right.z, forward.z, up.z);
			Vec3 pos = target->GetPosition() + toCam * mInternalParams.dist;
			SetTransformation(pos, Quat(rot));
			mUserParams.Clear();
			mPrevTargetPos = target->GetPosition();
		}
	}
示例#2
0
    static Transform LookAtRH(const Vec3 eye, const Vec3 at, const Vec3 up)
    {
        Vec3 n = (eye - at).Normalized();
        Vec3 u = up.Cross(n).Normalized();
        Vec3 v = n.Cross(u);

        float w = sqrtf(1.0f + u.x + v.y + n.z) * 0.5f;
        float w4 = 1.0f / (4.0f * w);
        
        return Transform(   Vec3(-u.Dot(eye), -v.Dot(eye), -n.Dot(eye)), // Position
                            Quat((v.z-n.y) * w4, (n.x-u.z) * w4, (u.y-v.x) * w4, -w).Normalized(), // Rotation
                            1); // Scale

    }
void CFlashUIWorldScreenPosNode::GetScreenPosFromWorld(IUIElement* pInstance, Vec3& pos /*in/out*/, Vec3& offset /*in/out*/, bool bScaleMode)
{
    // get current camera matrix
    const CCamera& cam = GetISystem()->GetViewCamera();
    const Matrix34& camMat = cam.GetMatrix();

    // add offset to position
    const Vec3 vFaceingPos = camMat.GetTranslation() - camMat.GetColumn1() * 1000.f;
    const Vec3 vDir = (pos - vFaceingPos).GetNormalizedFast();
    const Vec3 vOffsetX = vDir.Cross(Vec3Constants<float>::fVec3_OneZ).GetNormalizedFast() * offset.x;
    const Vec3 vOffsetY = vDir * offset.y;
    const Vec3 vOffsetZ = Vec3(0, 0, offset.z);
    const Vec3 vOffset = vOffsetX + vOffsetY + vOffsetZ;
    pos += vOffset;

    Vec2 borders;
    float scale;
    Vec3 flashPos;
    pInstance->WorldToFlash(camMat, pos, flashPos, borders, scale, bScaleMode);

    // return flashpos in pos
    pos = flashPos;

    // store overflow in offset x/y and scale in z
    offset.x = borders.x;
    offset.y = borders.y;
    offset.z = scale;
}
示例#4
0
void CDeflectorShield::ShootDeflectedEnergy(const CDeflectorShield::SDeflectedEnergy& energy)
{
	if (!m_pAmmoClass)
		return;
	CProjectile* pEnergyBlast = g_pGame->GetWeaponSystem()->SpawnAmmo(m_pAmmoClass, false);
	if (!pEnergyBlast)
		return;

	const Matrix34& worldTransform = GetEntity()->GetWorldTM();

	const float positionBias = 0.05f;

	const Vec3 worldReflectPos = worldTransform.TransformPoint(energy.m_localPosition);
	const Vec3 worldReflectDir = worldTransform.TransformVector(energy.m_localDirection);

	const Vec3 worldSpreadU = worldReflectDir.GetOrthogonal();
	const Vec3 worldSpreadV = worldReflectDir.Cross(worldSpreadU);

	const float spreadOffset = cry_random(0.0f, m_spread);
	
	const Vec3 position = worldReflectPos + worldReflectDir * positionBias;
	Vec3 direction = 
		worldReflectDir + 
		(worldSpreadU * cry_random(0.0f, m_spread)) + 
		(worldSpreadV * cry_random(0.0f, m_spread));
	direction.Normalize();

	CProjectile::SProjectileDesc projectileDesc(
		0, 0, 0, energy.m_damage, m_dropMinDistance, m_dropPerMeter, float(m_minDamage), m_hitTypeId,
		0, false);
	pEnergyBlast->SetParams(projectileDesc);
	pEnergyBlast->Launch(position, direction, Vec3(ZERO));
}
示例#5
0
    void UnderWaterGodRay::_updateProjector()
    {
        Plane p(Vec3(0, 1, 0), mWaterPosition);
        Vec3 sunDir = Environment::Instance()->GetEvParam()->SunDir;
        Vec3 sunPos = Environment::Instance()->GetEvParam()->SunPos;
        Ray r(sunPos, sunDir);

        RayIntersectionInfo info = r.Intersection(p);

        mEnable = info.iterscetion;

        mProjPosition = sunPos + sunDir * info.distance;

        Vec3 y(0, 1, 0);

        if (sunDir.Dot(y) < 0.001)
            y = Vec3(0, 0, -1);

        Vec3 x = y.Cross(sunDir);
        y = sunDir.Cross(x);
        
        mProjMatrix.MakeRotationAxis(x, y, sunDir);
        mProjMatrix._41 = mProjPosition.x;
        mProjMatrix._42 = mProjPosition.y;
        mProjMatrix._43 = mProjPosition.z;
    }
示例#6
0
inline float AngleBetweenVectors( const Vec3 &v1,const Vec3 &v2 )
{
	float a = acos_tpl(v1.Dot(v2));
	Vec3 r = v1.Cross(v2);
	if (r.z < 0)
		a = -a;
	return a;
}
Ang3 CVehicleSeatActionOrientateBoneToView::GetDesiredViewAngles(const Vec3& lookPos, const Vec3& aimPos) const
{
	Vec3 forwardDir = (aimPos - lookPos).GetNormalized();
	Vec3 upDir = Vec3(0.f, 0.f, 1.f);
	Vec3 sideDir = forwardDir.Cross(upDir);
	sideDir.Normalize();
	upDir = sideDir.Cross(forwardDir);
	upDir.Normalize();

	Matrix34 matrix;
	matrix.SetFromVectors(sideDir, forwardDir, upDir, Vec3(0.f, 0.f, 0.f));

	Ang3 lookAngles;
	lookAngles.SetAnglesXYZ(matrix);

	return lookAngles;
}
示例#8
0
// Ad-hoc
void CFlyer::ProcessMovement(float frameTime)
{
	frameTime = min(1.f, frameTime);

	float desiredSpeed = m_vDesiredVelocity.GetLength();
	const float maxDeltaSpeed = 100.f;

	float deltaSpeed = min(maxDeltaSpeed, fabsf(desiredSpeed - m_stats.speed));

	// Advance "m_velocity" towards "m_vDesiredVelocity" at the speed proportional to (1 / square(deltaSpeed))
	Interpolate(
		m_velocity,
		m_vDesiredVelocity,
		2.5f * ((deltaSpeed > 0.f) ? min(frameTime, 2.f / square(deltaSpeed)) : frameTime),
		1.f);

	Quat desiredVelocityQuat = m_qDesiredRotation;

	// pitch/roll
	if (desiredSpeed > 0.f && m_stats.speed > 0.f)
	{
		const Vec3& vUp = Vec3Constants<float>::fVec3_OneZ;
		Vec3 vForward = m_velocity.GetNormalized();

		// If the direction is not too vertical
		if (fabs(vForward.dot(vUp)) < cosf(DEG2RAD(3.f)))
		{
			vForward.z = 0;
			vForward.NormalizeSafe();
			Vec3 vRight = vForward.Cross(vUp);
			vRight.NormalizeSafe();

			Vec3 vDesiredVelocityNormalized = m_vDesiredVelocity.GetNormalized();

			// Roll in an aircraft-like manner
			float cofRoll = 6.f * vRight.dot(vDesiredVelocityNormalized) * (m_stats.speed / maxDeltaSpeed);
			clamp(cofRoll, -1.f, 1.f);
			desiredVelocityQuat *= Quat::CreateRotationY(DEG2RAD(60.f) * cofRoll); 

			float cofPitch = vDesiredVelocityNormalized.dot(vForward) * (deltaSpeed / maxDeltaSpeed);
			clamp(cofPitch, -1.f, 1.f);
			desiredVelocityQuat *= Quat::CreateRotationX(DEG2RAD(-60.f) * cofPitch); 
		}
	}

	float cofRot = 2.5f * ((deltaSpeed > 0.f) ? min(frameTime, 1.f / square(deltaSpeed)) : frameTime);
	clamp(cofRot, 0.f, 1.f);
	const Quat& qRotation = GetEntity()->GetRotation();
	Quat newRot = Quat::CreateSlerp(qRotation, desiredVelocityQuat, cofRot);
	m_moveRequest.rotation = qRotation.GetInverted() * newRot;
	m_moveRequest.rotation.Normalize();

	m_moveRequest.velocity = m_velocity;

	m_moveRequest.type = eCMT_Fly;
}
void CVehicleMovementAerodynamic::UpdateWing(SWing *_pWing,float _fAngle,float _fDeltaTime)
{
	Matrix34 matWing = m_pEntity->GetWorldTM() * Matrix33::CreateRotationXYZ(Ang3(DEG2RAD(_pWing->fAngleX),
																																								DEG2RAD(_pWing->fAngleY),
																																								DEG2RAD(_pWing->fAngleZ))).GetInverted();

	Vec3 vRight	= matWing.GetColumn(0);
	Vec3 vLook	= matWing.GetColumn(1);
	Vec3 vUp		= matWing.GetColumn(2);

	pe_status_dynamics StatusDynamics;
	GetPhysics()->GetStatus(&StatusDynamics);

	// v(relativepoint) = v + w^(relativepoint-center)
	Vec3 vVelocity = StatusDynamics.v + StatusDynamics.w.Cross(m_pEntity->GetWorldTM().TransformVector(_pWing->vPos));
	Vec3 vVelocityNormalized = vVelocity.GetNormalizedSafe(vLook);

	// TODO:

	float fAngleOfAttack = RAD2DEG(asin(vRight.Dot(vVelocityNormalized.Cross(vLook))));

	DumpText("AoA=%f",fAngleOfAttack);

	fAngleOfAttack += _fAngle;

	float Cl = GetCoefficient(_pWing->pLiftPointsMap,fAngleOfAttack) * _pWing->fCl;
	float Cd = GetCoefficient(_pWing->pDragPointsMap,fAngleOfAttack) * _pWing->fCd;

	Vec3 vVelocityNormal = vRight.Cross(vVelocityNormalized).GetNormalized();

	float fVelocitySquared = vVelocity.len2();

	const float c_fDynamicPressure = 1.293f;

	float fLift = 0.5f * c_fDynamicPressure * _pWing->fSurface * Cl * fVelocitySquared * _fDeltaTime;
	float fDrag = 0.5f * c_fDynamicPressure * _pWing->fSurface * Cd * fVelocitySquared * _fDeltaTime;

	Vec3 vLiftImpulse = +fLift * vVelocityNormal;
	Vec3 vDragImpulse = -fDrag * vVelocityNormalized;

	AddForce(&vLiftImpulse,&_pWing->vPos,ColorF(0,1,0,1));
	AddForce(&vDragImpulse,&_pWing->vPos,ColorF(1,0,1,1));
}
示例#10
0
Matrix Matrix::LookAt(const Vec3& position, const Vec3& target, const Vec3& up) {
  /// Generate view matrix for position camera 	
  /// http://wiki.delphigl.com/index.php/gluLookAt
  const float epsilon = 0.001f;

  Vec3 f = -(target - position).Normal();
  Vec3 s = -f.Cross(up.Normal());
  float sl = s.Length();
  if (fabs(sl) < epsilon) {
    s = -f.Cross(Vec3(up.y, up.z, up.x).Normal());
    sl = s.Length();
  }
  s /= sl;
  Vec3 u = s.Cross(f);

  Matrix m;
  m.m[0] = s.x;	  m.m[1] = s.y;	  m.m[2] = s.z;	  m.m[3] = 0;
  m.m[4] = u.x;	  m.m[5] = u.y;	  m.m[6] = u.z;	  m.m[7] = 0;
  m.m[8] = -f.x;	m.m[9] = -f.y;	m.m[10] = -f.z;	m.m[11] = 0;
  m.m[12] = 0;		m.m[13] = 0;		m.m[14] = 0;		m.m[15] = 1;
  return Translate(-position) * m;
}
Vec3 RapidTrajectoryGenerator::GetOmega(double t, double timeStep) const
{
  //Calculates the body rates necessary at time t, to rotate the normal vector.
  //The result is coordinated in the world frame, i.e. would have to be rotated into a
  //body frame.
	const Vec3 n0 = GetNormalVector(t);
	const Vec3 n1 = GetNormalVector(t + timeStep);

	const Vec3 crossProd = n0.Cross(n1); //direction of omega, in inertial axes

	if (crossProd.GetNorm2()) return  (acos(n0.Dot(n1))/timeStep)*crossProd.GetUnitVector();
	else return Vec3(0, 0, 0);
}
示例#12
0
文件: main.cpp 项目: lanixXx/scratch
        inline Vec3 RotatedBy(Vec3 const &axisVec, double angleDegCCW)
        {
            if(!angleDegCCW)
            {   return Vec3(this->x,this->y,this->z);   }

            Vec3 rotatedVec;
            double angleRad = angleDegCCW*3.141592653589/180.0;
            rotatedVec = this->ScaledBy(cos(angleRad)) +
                         (axisVec.Cross(*this)).ScaledBy(sin(angleRad)) +
                         axisVec.ScaledBy(axisVec.Dot(*this)).ScaledBy(1-cos(angleRad));

            return rotatedVec;
        }
示例#13
0
// MakeLookAt
//------------------------------------------------------------------------------
void Mat44::MakeLookAt( const Vec3 & pos, const Vec3 & lookAt, const Vec3 & upVector )
{
    // generate the forward vector
    Vec3 forward( pos - lookAt );
    forward.Normalise();

    Vec3 right = upVector.Cross( forward );
    right.Normalise();

    Vec3 up = forward.Cross( right );
    up.Normalise();

    col0 = Vec4( right.x, up.x, forward.x, 0.0f );
    col1 = Vec4( right.y, up.y, forward.y, 0.0f ),
    col2 = Vec4( right.z, up.z, forward.z, 0.0f ),
    col3 = Vec4( -right.Dot( pos ), -up.Dot( pos ), -forward.Dot( pos ), 1.0f );
}
void CStickyProjectile::CalculateLocationForStick( const IEntity& projectile, const Vec3& collPos, const Vec3& collNormal, QuatT& outLocation ) const
{
	if(m_flags&eSF_OrientateToCollNormal)
	{
		const float bigz = cry_fabsf(collNormal.z)-cry_fabsf(collNormal.y);
		const Vec3 temp(0.f,(float)__fsel(bigz,1.f,0.f),(float)__fsel(bigz,0.f,1.f));
		outLocation.q = Quat(Matrix33::CreateOrientation( temp.Cross(collNormal), -collNormal, 0));

		AABB aabb;
		projectile.GetLocalBounds(aabb);
		outLocation.t = collPos + (outLocation.q.GetColumn2() * ((aabb.max.y-aabb.min.y)*0.5f));
	}
	else
	{
		outLocation.q = projectile.GetRotation();
		outLocation.t = collPos + (outLocation.q.GetColumn1() * 0.1f);
	}
}
示例#15
0
void CCameraRayScan::ShootRays(const Vec3 &rayPos, const Vec3 &rayDir, IPhysicalEntity **pSkipEnts, int numSkipEnts)
{

	//shoot rays for all ray_hits
	const Vec3 dirNorm = rayDir.normalized();
	const Vec3 right = dirNorm.Cross(Vec3Constants<float>::fVec3_OneZ);
	const Vec3 rightOff = right * 0.15f;
	const Vec3 rightDir = right * 0.15f;
	const float len = rayDir.len() * RAY_SCAN_BUFFER_SCALE; //add some distance to be sure that the view is free

	const Vec3 rayPos2 = rayPos + (dirNorm * RAY_SCAN_OFFSET_DISTANCE); //move the rays away from the head to prevent clipping

	//center ray
	Vec3 tempPos = rayPos2;
	Vec3 tempDir = dirNorm;
	ShootRayInt(eRAY_CENTER, tempPos, tempDir, len, pSkipEnts, numSkipEnts);

	tempDir = (dirNorm - rightDir + g_vRayUpDir).normalized();
	tempPos = rayPos2 - rightOff + g_vRayUpOffset;
	ShootRayInt(eRAY_TOP_LEFT, tempPos, tempDir, len, pSkipEnts, numSkipEnts);

	tempDir = (dirNorm + rightDir + g_vRayUpDir).normalized();
	tempPos = rayPos2 + rightOff + g_vRayUpOffset;
	ShootRayInt(eRAY_TOP_RIGHT, tempPos, tempDir, len, pSkipEnts, numSkipEnts);

	tempDir = (dirNorm - rightDir - g_vRayUpDir).normalized();
	tempPos = rayPos2 - rightOff - g_vRayUpOffset;
	ShootRayInt(eRAY_BOTTOM_LEFT, tempPos, tempDir, len, pSkipEnts, numSkipEnts);

	tempDir = (dirNorm + rightDir - g_vRayUpDir).normalized();
	tempPos = rayPos2 + rightOff - g_vRayUpOffset;
	ShootRayInt(eRAY_BOTTOM_RIGHT, tempPos, tempDir, len, pSkipEnts, numSkipEnts);

	tempDir = (dirNorm + g_vRayUpDir).normalized();
	tempPos = rayPos2 + g_vRayUpOffset * 2.0f;
	ShootRayInt(eRAY_TOP_CENTER, tempPos, tempDir, len, pSkipEnts, numSkipEnts);

	tempDir = (dirNorm - g_vRayUpDir).normalized();
	tempPos = rayPos2 - g_vRayUpOffset * 2.0f;
	ShootRayInt(eRAY_BOTTOM_CENTER, tempPos, tempDir, len, pSkipEnts, numSkipEnts);
}
示例#16
0
void CUIEntityDynTexTag::UpdateView(const SViewParams &viewParams)
{
    static const Quat rot90Deg = Quat::CreateRotationXYZ(Ang3(gf_PI * 0.5f, 0, 0));
    const Vec3 vSafeVec = viewParams.rotation.GetColumn1();

    for(TTags::iterator it = m_Tags.begin(); it != m_Tags.end(); ++it)
    {
        IEntity *pOwner = gEnv->pEntitySystem->GetEntity(it->OwnerId);
        IEntity *pTagEntity = gEnv->pEntitySystem->GetEntity(it->TagEntityId);

        if(pOwner && pTagEntity)
        {
            const Vec3 offset = it->fLerp < 1 ? Vec3::CreateLerp(it->vOffset, it->vNewOffset, it->fLerp) : it->vOffset;
            const Vec3 &vPos = pOwner->GetWorldPos();
            const Vec3 vFaceingPos = viewParams.position - vSafeVec * 1000.f;
            const Vec3 vDir = (vPos - vFaceingPos).GetNormalizedSafe(vSafeVec);
            const Vec3 vOffsetX = vDir.Cross(Vec3Constants<float>::fVec3_OneZ).GetNormalized() * offset.x;
            const Vec3 vOffsetY = vDir * offset.y;
            const Vec3 vOffsetZ = Vec3(0, 0, offset.z);
            const Vec3 vOffset = vOffsetX + vOffsetY + vOffsetZ;


            const Vec3 vNewPos = vPos + vOffset;
            const Vec3 vNewDir = (vNewPos - vFaceingPos).GetNormalizedSafe(vSafeVec);

            const Quat qTagRot = Quat::CreateRotationVDir(vNewDir) * rot90Deg; // rotate 90 degrees around X-Axis
            pTagEntity->SetPos(vNewPos);
            pTagEntity->SetRotation(qTagRot);

            if(it->fLerp < 1)
            {
                assert(it->fSpeed > 0);
                it->fLerp += viewParams.frameTime * it->fSpeed;
                it->vOffset = offset;
            }
        }
    }
}
//------------------------------------------------------------------------
Quat CVehicleViewFirstPerson::GetWorldRotGoal()
{
	// now get fitting vehicle world pos/rot
	Quat vehicleWorldRot = m_pVehicle->GetEntity()->GetWorldRotation();

	if (m_relToHorizon > 0.f)
	{
		Quat vehicleRot = m_pVehicle->GetEntity()->GetRotation();
		Vec3 vx = vehicleRot * Vec3(1, 0, 0);
		Vec3 vy = vehicleRot * Vec3(0, 1, 0);
		Vec3 vz = vehicleRot * Vec3(0, 0, 1);

		// vx is "correct"
		vy = (1.0f - m_relToHorizon) * Vec3(0, 0, 1).Cross(vx) + m_relToHorizon * vy;
		vy.NormalizeSafe(Vec3Constants<float>::fVec3_OneY);
		vz = vx.Cross(vy);
		vz.NormalizeSafe(Vec3Constants<float>::fVec3_OneZ);

		vehicleWorldRot = Quat(Matrix33::CreateFromVectors(vx, vy, vz));      
	}

	return vehicleWorldRot;
}
示例#18
0
void InitIntersection(Intersection &intersection, DWORD faceIndex, FLOAT dist, FLOAT u, FLOAT v, ActorId actorId, WORD* pIndices, T* pVertices, const Mat4x4& matWorld)
{
	intersection.m_dwFace = faceIndex;
	intersection.m_fDist = dist;
	intersection.m_fBary1 = u;
	intersection.m_fBary2 = v;

	T* v0 = &pVertices[pIndices[3 * faceIndex + 0]];
	T* v1 = &pVertices[pIndices[3 * faceIndex + 1]];
	T* v2 = &pVertices[pIndices[3 * faceIndex + 2]];

	Vec3 a = v0->position - v1->position;
	Vec3 b = v2->position - v1->position;

	Vec3 cross = a.Cross(b);
	cross /= cross.Length();

	Vec3 actorLoc = XMVectorBaryCentric(v0->position, v1->position, v2->position, intersection.m_fBary1, intersection.m_fBary2);
	intersection.m_actorLoc = actorLoc;
	intersection.m_worldLoc = matWorld.Xform(actorLoc);
	intersection.m_actorId = actorId;
	intersection.m_normal = cross;
}
示例#19
0
void WatchMeProcess::VOnUpdate(unsigned long deltaMs)
{
    StrongActorPtr pTarget = MakeStrongPtr(g_pApp->m_pGame->VGetActor(m_target));
	StrongActorPtr pMe = MakeStrongPtr(g_pApp->m_pGame->VGetActor(m_me));

    shared_ptr<TransformComponent> pTargetTransform = MakeStrongPtr(pTarget->GetComponent<TransformComponent>(TransformComponent::g_Name));
    shared_ptr<TransformComponent> pMyTransform = MakeStrongPtr(pMe->GetComponent<TransformComponent>(TransformComponent::g_Name));

	if (!pTarget || !pMe || !pTargetTransform || !pMyTransform)
	{
		GCC_ERROR("This shouldn't happen");
		Fail();
	}

	Vec3 targetPos = pTargetTransform->GetPosition();
	Mat4x4 myTransform = pMyTransform->GetTransform();
	Vec3 myDir = myTransform.GetDirection();
	myDir = Vec3(0.0f, 0.0f, 1.0f);
	Vec3 myPos = pMyTransform->GetPosition();

	Vec3 toTarget = targetPos - myPos;
	toTarget.Normalize();

	float dotProduct = myDir.Dot(toTarget);
	Vec3 crossProduct = myDir.Cross(toTarget);

	float angleInRadians = acos(dotProduct);

	if (crossProduct.y < 0)
		angleInRadians = -angleInRadians;
	
	Mat4x4 rotation;
	rotation.BuildRotationY(angleInRadians);
	rotation.SetPosition(myPos);
	pMyTransform->SetTransform(rotation);
}
int CFlowConvoyNode::OnPhysicsPostStep(const EventPhys * pEvent)
{
	FUNCTION_PROFILER(GetISystem(), PROFILE_GAME);

  if(m_bFirstUpdate)
    return 0; //after QuickLoad OnPhysicsPostStep called before ProcessEvent

	const EventPhysPostStep *pPhysPostStepEvent = (const EventPhysPostStep *)pEvent;

	IPhysicalEntity *pEventPhysEnt = pPhysPostStepEvent->pEntity;

	Vec3 posBack, posFront, posCenter;

	for (size_t i = 0; i < m_coaches.size(); ++i)
	{
		IPhysicalEntity *pPhysEnt = m_coaches[i].m_pEntity->GetPhysics();

		if (pEventPhysEnt == pPhysEnt)
		{
			if (m_ShiftTime > 0.0f)
			{
				m_speed = m_speed * (1.0f - breakValue * pPhysPostStepEvent->dt / m_MaxShiftTime);
				m_ShiftTime -= pPhysPostStepEvent->dt;
			}
			else
			{
				m_speed = m_speed + min(1.0f, (pPhysPostStepEvent->dt / 5.0f)) * (m_desiredSpeed - m_speed);
			}
		

			float speed = (m_splitCoachIndex > 0 && (int)i >= m_splitCoachIndex) ? m_splitSpeed : m_speed;
			float distance = (m_coaches[i].m_distanceOnPath += pPhysPostStepEvent->dt * speed);
			
			if(m_splitCoachIndex>0)
			{//train splitted
				if(i==m_splitCoachIndex-1) // update m_distanceOnPath for serialization
					m_distanceOnPath=distance-m_coaches[i].m_coachOffset;
				else if(i==m_coaches.size()-1) // update m_splitDistanceOnPath for serialization
					m_splitDistanceOnPath=distance-m_coaches[i].m_coachOffset;
			}
			else
			{//train in one piece
				if(i==m_coaches.size()-1)// update m_distanceOnPath for serialization
					m_distanceOnPath=distance-m_coaches[i].m_coachOffset;
			}

			posBack  = m_path.GetPointAlongPath(distance - m_coaches[i].m_wheelDistance, m_coaches[i].m_backWheelIterator[0]);
			posFront = m_path.GetPointAlongPath(distance + m_coaches[i].m_wheelDistance, m_coaches[i].m_frontWheelIterator[0]);
			posCenter = (posBack+posFront)*0.5f;


			Vec3 posDiff = posFront - posBack;
			float magnitude = posDiff.GetLength();

			if (magnitude > FLT_EPSILON)
			{
				posDiff *= 1.0f / magnitude;

				pe_params_pos ppos;
				ppos.pos = posCenter;
				ppos.q = Quat::CreateRotationVDir(posDiff);
				if (m_bXAxisFwd)
					ppos.q *= Quat::CreateRotationZ(gf_PI*-0.5f);
				pPhysEnt->SetParams(&ppos, 0 /* bThreadSafe=0 */); // as we are calling from the physics thread

				Vec3 futurePositionBack, futurePositionFront;
				futurePositionBack  = m_path.GetPointAlongPath(distance + PATH_DERIVATION_TIME * speed - m_coaches[i].m_wheelDistance, m_coaches[i].m_backWheelIterator[1]);
				futurePositionFront = m_path.GetPointAlongPath(distance + PATH_DERIVATION_TIME * speed + m_coaches[i].m_wheelDistance, m_coaches[i].m_frontWheelIterator[1]);

				Vec3 futurePosDiff = futurePositionFront - futurePositionBack;
				magnitude = futurePosDiff.GetLength();

				if (magnitude > FLT_EPSILON)
				{
					futurePosDiff *= 1.0f / magnitude;

					pe_action_set_velocity setVel;
					setVel.v = ((futurePositionBack+ futurePositionFront)*0.5f - posCenter) * (1.0f/PATH_DERIVATION_TIME);

					//Vec3 dir=(posFront-posBack).GetNormalized();
					//Vec3 future_dir=(futurePositionFront-futurePositionBack).GetNormalized();
					Vec3 w=posDiff.Cross(futurePosDiff);
					float angle=cry_asinf(w.GetLength());
					setVel.w=(angle/PATH_DERIVATION_TIME)*w.GetNormalized();
					pPhysEnt->Action(&setVel, 0 /* bThreadSafe=0 */); // as we are calling from the physics thread
					break;
				}
			}
		}
	}

	// Done processing once we reach end of path
	if (m_atEndOfPath)
		m_processNode = false;

	return 0;
}
示例#21
0
文件: Mesh.cpp 项目: ecntrk/ILFcore
inline void Mesh::addTriangle(int vu, int vv, int vw,
							  int nu, int nv, int nw,
							  int tu, int tv, int tw)
{
	int fvu = vu, fvv = vv, fvw = vw,
		fnu = nu, fnv = nv, fnw = nw,
		ftu = tu, ftv = tv, ftw = tw;

	// VP (Vedad and Piotr) test - Flip incorrect normals
	if (fixNormals)
	{
		Vec3 faceNormal;

		const Vec3 edge1 = s->v[startVertex + fvv] - s->v[startVertex + fvu],
				   edge2 = s->v[startVertex + fvw] - s->v[startVertex + fvu];
		faceNormal.Cross(edge1, edge2);
		faceNormal.Normalize();

		Vec3 faceNormalFromVN = (s->vn[startNormal + fnu] +
								 s->vn[startNormal + fnv] +
								 s->vn[startNormal + fnw]);

		faceNormalFromVN.Normalize();

		if (faceNormal.Dot(faceNormalFromVN) <= 0.0f)
		{
			fvu = vw; fvv = vv; fvw = vu;
			fnu = nw, fnv = nv, fnw = nu;
			ftu = tw, ftv = tv, ftw = tu;
		}
	}

	// Change winding of model (vertices and their normals)
	if (flipWinding)
	{
		fvu = vw; fvv = vv; fvw = vu;
		fnu = nw, fnv = nv, fnw = nu;
		ftu = tw, ftv = tv, ftw = tu;
	}

	fvu += startVertex; fvv += startVertex; fvw += startVertex;
	fnu += startNormal; fnv += startNormal; fnw += startNormal;
	ftu += startTex; ftv += startTex; ftw += startTex;

	if (curbsdf == NULL)
		curbsdf = bsdf;

	// Add index entries
	s->index.Add(VecIndex(fvu, fvv, fvw));

	Vec3 *v[3], *n[3], *t[3];

	// Set all initially to NULL
	n[0] = NULL; n[1] = NULL; n[2] = NULL;
	t[0] = NULL; t[1] = NULL; t[2] = NULL;

	v[0] = &s->v[fvu];
	v[1] = &s->v[fvv];
	v[2] = &s->v[fvw];

	if (nu != 0 && nv != 0 && nw != 0)
	{
		n[0] = &s->vn[fnu];
		n[1] = &s->vn[fnv];
		n[2] = &s->vn[fnw];

		s->vnIndex.Add(VecIndex(fnu, fnv, fnw));
	}
	else
		s->vnIndex.Add(VecIndex(-1, -1, -1));

	if (tu != 0 && tv != 0 && tw != 0)
	{
		t[0] = &s->tex[ftu];
		t[1] = &s->tex[ftv];
		t[2] = &s->tex[ftw];
		s->texIndex.Add(VecIndex(ftu, ftv, ftw));
	}
	else
		s->texIndex.Add(VecIndex(-1, -1, -1));

	s->t.Add(MollerTriangle(s->t.size(), curbsdf,
						    v[0], v[1], v[2],
					        n[0], n[1], n[2],
							t[0], t[1], t[2]));

	// Store face that these verticies belong to
	vertFaces[fvu - startVertex - 1].push_back(s->t.size() - 1);
	vertFaces[fvv - startVertex - 1].push_back(s->t.size() - 1);
	vertFaces[fvw - startVertex - 1].push_back(s->t.size() - 1);
}
示例#22
0
//------------------------------------------------------------------------
void CItem::UpdateMounted(float frameTime)
{
	IRenderAuxGeom* pAuxGeom = gEnv->pRenderer->GetIRenderAuxGeom();

	if (!m_ownerId || !m_stats.mounted)
		return;

	CActor *pActor = GetOwnerActor();
	if (!pActor)
		return;

	CheckViewChange();

  if (true)
  {  
	  if (IsClient())
	  {
		  ICharacterInstance *pCharacter = GetEntity()->GetCharacter(eIGS_FirstPerson);

		  if (pCharacter && !m_idleAnimation[eIGS_FirstPerson].empty() && pCharacter->GetISkeletonAnim()->GetNumAnimsInFIFO(0)<1)
			  PlayAction(m_idleAnimation[eIGS_FirstPerson], 0, true);
	  }

		// need to explicitly update characters at this point
		// cause the entity system update occered earlier, with the last position
		for (int i=0; i<eIGS_Last; i++)
		{
			if (GetEntity()->GetSlotFlags(i)&ENTITY_SLOT_RENDER)
			{
				ICharacterInstance *pCharacter = GetEntity()->GetCharacter(i);
				if (pCharacter)
				{
					Matrix34 mloc = GetEntity()->GetSlotLocalTM(i,false);
					Matrix34 m34 = GetEntity()->GetWorldTM()*mloc;
					QuatT renderLocation = QuatT(m34);
					pCharacter->GetISkeletonPose()->SetForceSkeletonUpdate(9);
					pCharacter->SkeletonPreProcess(renderLocation, renderLocation, GetISystem()->GetViewCamera(),0x55 );
					pCharacter->SetPostProcessParameter(renderLocation, renderLocation, 0, 0.0f, 0x55 );		
				}
			}
		}

	//	f32 fColor[4] = {1,1,0,1};
	//	f32 g_YLine=60.0f;
	//	gEnv->pRenderer->Draw2dLabel( 1,g_YLine, 1.3f, fColor, false, "Mounted Gun Code" ); 

		//adjust the orientation of the gun based on the aim-direction


		SMovementState info;
		IMovementController* pMC = pActor->GetMovementController();		
		pMC->GetMovementState(info);
		Vec3 dir = info.aimDirection.GetNormalized();
		Matrix34 tm = Matrix33::CreateRotationVDir(dir);
		Vec3 vGunXAxis=tm.GetColumn0();

		if (pActor->GetLinkedVehicle()==0)
		{
			if (pMC)
			{						
				if(!pActor->IsPlayer())
				{
					// prevent snapping direction
					Vec3 currentDir = GetEntity()->GetWorldRotation().GetColumn1();
					float dot = currentDir.Dot(dir);
					dot = CLAMP(dot,-1,1);
					float reqAngle = cry_acosf(dot);
					const float maxRotSpeed = 2.0f;
					float maxAngle = frameTime * maxRotSpeed;
					if(fabs(reqAngle) > maxAngle)
					{
						Vec3 axis = currentDir.Cross(dir);
						if(axis.GetLengthSquared()>0.001f) // current dir and new dir are enough different
							dir = currentDir.GetRotated(axis.GetNormalized(),sgn(reqAngle)*maxAngle);
					}
				}				
				//adjust the orientation of the gun based on the aim-direction
				tm = Matrix33::CreateRotationVDir(dir);
				Vec3 vWPos=GetEntity()->GetWorldPos();
				tm.SetTranslation(vWPos);
				GetEntity()->SetWorldTM(tm);  //set the new orientation of the mounted gun

				vGunXAxis=tm.GetColumn0();
				Vec3 vInitialAimDirection = m_stats.mount_dir;
				Matrix33 vInitialPlayerOrientation = Matrix33::CreateRotationVDir(vInitialAimDirection);
				assert( vInitialAimDirection.IsUnit() );

	  		Vec3 newp;

				if (pActor->IsThirdPerson())
				{
					//third person
					f32 dist = m_mountparams.body_distance*1.3f;
					Vec3 oldp = pActor->GetEntity()->GetWorldPos();
					newp = GetEntity()->GetWorldPos()-vInitialAimDirection*dist; //mounted gun
					newp.z = oldp.z;
				}
				else
				{
					//first person
					f32 fMoveBack = (1.0f+(dir.z*dir.z*dir.z*dir.z*4.0f))*0.75f;
					f32	dist = m_mountparams.eye_distance*fMoveBack;
					Vec3 oldp = pActor->GetEntity()->GetWorldPos();
					newp = GetEntity()->GetWorldPos()-dir*dist; //mounted gun
					//newp.z -= 0.75f;
					newp.z = oldp.z;
				}


				Matrix34 actortm(pActor->GetEntity()->GetWorldTM());

				//if (pActor->IsThirdPerson())
				actortm=vInitialPlayerOrientation;

				actortm.SetTranslation(newp);
				pActor->GetEntity()->SetWorldTM(actortm, ENTITY_XFORM_USER);
				pActor->GetAnimationGraphState()->SetInput("Action","gunnerMounted");
				
				//f32 g_YLine=80.0f;
				//gEnv->pRenderer->Draw2dLabel( 1,g_YLine, 1.3f, fColor, false, "Mounted Gun Active for FP and AI" ); 

				if (ICharacterInstance *pCharacter = pActor->GetEntity()->GetCharacter(0))
				{
					ISkeletonAnim *pSkeletonAnim = pCharacter->GetISkeletonAnim();
					assert(pSkeletonAnim);

					uint32 numAnimsLayer = pSkeletonAnim->GetNumAnimsInFIFO(0);
					for(uint32 i=0; i<numAnimsLayer; i++)
					{
						CAnimation &animation = pSkeletonAnim->GetAnimFromFIFO(0, i);
						if (animation.m_AnimParams.m_nFlags & CA_MANUAL_UPDATE)
						{
							f32 aimrad = Ang3::CreateRadZ(Vec2(vInitialAimDirection),Vec2(dir));
							animation.m_fAnimTime = clamp_tpl(aimrad/gf_PI,-1.0f,+1.0f)*0.5f+0.5f;
							//if (pActor->IsThirdPerson()==0)
								//animation.m_fAnimTime=0.6f; //Ivo & Benito: high advanced future code. don't ask what it is 
							                                //Benito - Not needed any more ;)

							//f32 g_YLine=100.0f;
							//gEnv->pRenderer->Draw2dLabel( 1,g_YLine, 1.3f, fColor, false, "AnimTime: %f    MyAimAngle: %f deg:%   distance:%f", animation.m_fAnimTime, aimrad, RAD2DEG(aimrad),m_mountparams.body_distance ); 
						}
					}

				}

				m_stats.mount_last_aimdir = dir;
				
			}
		}
    
    if (ICharacterInstance* pCharInstance = pActor->GetEntity()->GetCharacter(0))
		{
      if (ISkeletonAnim* pSkeletonAnim = pCharInstance->GetISkeletonAnim())
      {   
        OldBlendSpace ap;				
        if (GetAimBlending(ap))
        {
					pSkeletonAnim->SetBlendSpaceOverride(eMotionParamID_TurnSpeed, 0.5f + 0.5f * ap.m_turn, true);
        }        
      }        
    } 

    UpdateIKMounted(pActor, vGunXAxis*0.1f);
   
		RequireUpdate(eIUS_General);
  }
}
示例#23
0
文件: main.cpp 项目: lanixXx/scratch
void buildPlaneGeometry(Vec3 const &vecCenter,
                        Vec3 const &vecNormal,
                        Vec3 const &vecUp,
                        double width, double height,
                        unsigned int widthSegments,
                        unsigned int heightSegments,
                        std::vector<Vec3> &vertexArray,
                        std::vector<Vec2> &texCoords,
                        std::vector<unsigned int> &triIdx)
{
    double segmentWidth = width/widthSegments;
    double segmentHeight = height/heightSegments;

    // build vertex attributes
    for(int i=0; i <= widthSegments; i++)   {   // rows
        for(int j=0; j <= heightSegments; j++)   {  // cols
            vertexArray.push_back(Vec3(i*segmentWidth,j*segmentHeight,0.0));
            texCoords.push_back(Vec2(i*segmentWidth/width,j*segmentHeight/height));
        }
    }

    // stitch faces together
    unsigned int vIdx = 0;
    for(int i=0; i < widthSegments; i++)   {    // rows
        for(int j=0; j < heightSegments; j++)   {   // cols
            triIdx.push_back(vIdx);
            triIdx.push_back(vIdx+heightSegments+1);
            triIdx.push_back(vIdx+heightSegments+2);

            triIdx.push_back(vIdx);
            triIdx.push_back(vIdx+heightSegments+2);
            triIdx.push_back(vIdx+1);

            vIdx++;
        }
        vIdx++;
    }

    // translate to origin, then rotate, then translate to center
    Vec3 vecTranslate(-1*width/2,-1*height/2,0);

    // transformed x,y,z
    Vec3 xformedx = vecUp.Cross(vecNormal).Normalized();
    Vec3 xformedy = vecUp.Normalized();
    Vec3 xformedz = vecNormal.Normalized();

    for(int i=0; i < vertexArray.size(); i++)   {
        // translate relative to (0,0,0)
        vertexArray[i] = vertexArray[i] + vecTranslate;

        // xform matrix multiplication (col. major mult.)
        double vx = vertexArray[i].x;
        double vy = vertexArray[i].y;
        double vz = vertexArray[i].z;

        vx = xformedx.x*vertexArray[i].x +
             xformedy.x*vertexArray[i].y +
             xformedz.x*vertexArray[i].z;

        vy = xformedx.y*vertexArray[i].x +
             xformedy.y*vertexArray[i].y +
             xformedz.y*vertexArray[i].z;

        vz = xformedx.z*vertexArray[i].x +
             xformedy.z*vertexArray[i].y +
             xformedz.z*vertexArray[i].z;

        vertexArray[i].x = vx + vecCenter.x;
        vertexArray[i].y = vy + vecCenter.y;
        vertexArray[i].z = vz + vecCenter.z;

        //
        Vec3 earthSurfPt;
        Vec3 rayOrigin = vertexArray[i].Normalized().ScaledBy(ELL_SEMI_MAJOR*1.1);  // so its closer to the side we want
        Vec3 rayDirn = vertexArray[i].Normalized().ScaledBy(-1); // invert direction
        calcRayEarthIntersection(rayOrigin,rayDirn,earthSurfPt);
        vertexArray[i] = earthSurfPt;
    }
}
示例#24
0
文件: main.cpp 项目: lanixXx/scratch
void buildPolylineAsTriStrip(std::vector<Vec3> const &listPolylineVx,
                             double const polylineWidth,
                             std::vector<Vec3> &listVx,
                             std::vector<Vec2> &listTx,
                             double &polylineLength)
{
    size_t numPts = listPolylineVx.size();
    size_t numOffsets = (numPts-1)*2;   // 2 for each edge
    std::vector<Vec3> listOffsetPtsL(numOffsets);
    std::vector<Vec3> listOffsetPtsR(numOffsets);
    std::vector<Vec2> listOffsetTxL(numOffsets);
    std::vector<Vec2> listOffsetTxR(numOffsets);

    Vec3 vecNormal;                     // vector originating at the center of the earth
                                        // (0,0,0) to a vertex on the way

    Vec3 vecDirn;                       // vector along a given segment on the way

    Vec3 vecOffset;                     // vector normal to both vecPlaneNormal and
                                        // vecAlongSegment (used to create offset)

    Vec3 vecOffsetL,vecOffsetR;         // offsets from way center

    // keep track of edge distances and total length
    double totalLength = 0;
    std::vector<double> listEdgeDists(numPts,0);

    // we offset the polyline on both sides of the
    // centerline and stitch the resulting shape together

    // to account for self intersections or gaps that occur in
    // the 'inner' or 'outer' offsets, we use the perpendicular
    // bisector of the adjoining edges to find the inner edge
    // intersection and straight lines to fill outer edge gaps
    // (this provides a bevel/boxed joint effect)

    // in the resulting triangle strip, each 'joint' created
    // from adjacent edges in the original polyline contains
    // one degenerate triangle

    // [TODO: in MapRenderer, discard duplicate adjacent vertex data]

    // for each segment, create dirn and offset vecs
    size_t k=0;
    double offsetLength = polylineWidth/2;
    for(size_t i=1; i < numPts; i++)   {
        // offset vertex coordinates
        vecNormal = listPolylineVx[i];
        vecDirn   = listPolylineVx[i]-listPolylineVx[i-1];
        vecOffset = vecDirn.Cross(vecNormal).Normalized();

        vecOffsetL = vecOffset.ScaledBy(offsetLength);
        vecOffsetR = vecOffsetL.ScaledBy(-1.0);

        listOffsetPtsL[k] = listPolylineVx[i-1]+vecOffsetL;
        listOffsetPtsR[k] = listPolylineVx[i-1]+vecOffsetR; k++;

        listOffsetPtsL[k] = listPolylineVx[i]+vecOffsetL;
        listOffsetPtsR[k] = listPolylineVx[i]+vecOffsetR;   k++;

        // edge length and total polyline length
        double edgeLength = vecDirn.Magnitude();
        listEdgeDists[i] = listEdgeDists[i-1]+edgeLength;
        totalLength += edgeLength;
    }

    k=0;
    for(size_t i=1; i < numPts; i++)   {
        // offset texture coordinates
        listOffsetTxL[k].x = 0.0;
        listOffsetTxR[k].x = 1.0;
        listOffsetTxL[k].y = listEdgeDists[i-1]/totalLength;
        listOffsetTxR[k].y = listOffsetTxL[k].y;  k++;

        listOffsetTxL[k].x = 0.0;
        listOffsetTxR[k].x = 1.0;
        listOffsetTxL[k].y = listEdgeDists[i]/totalLength;
        listOffsetTxR[k].y = listOffsetTxL[k].y;  k++;
    }

    if(numPts > 2)   {
        // we only adjust the join vertices
        // if there's more than one edge
        for(size_t i=1; i < numPts-1; i++)
        {
//            continue;
            size_t idx = (i*2)-2;   // first idx for prev edge offset

            // determine the angle between two adjacent edges
            Vec3 edgePrev = (listPolylineVx[i-1]-listPolylineVx[i]).Normalized();
            Vec3 edgeNext = (listPolylineVx[i+1]-listPolylineVx[i]).Normalized();
            Vec3 edgeBisect = edgePrev+edgeNext;
            double edgeBisectLength = edgeBisect.Magnitude();
            std::cout << "edgeBisectLength:" << edgeBisect.Magnitude() << ", ";

            // special case: collinear edges
            if(edgeBisectLength < 0.001)   {
                listOffsetPtsL[idx+1] = listOffsetPtsL[idx+2];//listOffsetPtsR[idx+1];
                listOffsetPtsR[idx+1] = listOffsetPtsR[idx+2];//listOffsetPtsR[idx+2];
                continue;
            }

            // |AxB| = |A|*|B|*sinTheta
            double sinTheta = (edgePrev.Cross(edgeBisect)).Magnitude()/
                    (edgePrev.Magnitude()*edgeBisectLength);

            std::cout << "sinTheta:" << sinTheta << ", ";

            // special case:
            // * extreme angle between segments
            // * edge doubles back on itself [bad data]
            if(sinTheta < 0.33)   {
                listOffsetPtsL[idx+1] = listOffsetPtsR[idx+2];
                listOffsetPtsL[idx+2] = listOffsetPtsR[idx+1];
                continue;
            }

            // get the vertex coincident with the xsec of adjacent inside edges
            Vec3 vecBisect = edgeBisect.Normalized().ScaledBy(offsetLength/sinTheta);
            std::cout << "vecBisect:" << vecBisect.Magnitude() << std::endl;
            vecBisect = listPolylineVx[i]+vecBisect;


            // determine which side (left or right) corresponds
            // to the inner and outer offsets and move vertices
            double distToXsecL = listOffsetPtsL[idx+1].Distance2To(vecBisect);
            double distToXsecR = listOffsetPtsR[idx+1].Distance2To(vecBisect);
            if(distToXsecL < distToXsecR)   {       // left is the inner offset
                listOffsetPtsL[idx+1] = vecBisect;
                listOffsetPtsL[idx+2] = vecBisect;
            }
            else   {                                // right is the inner offset
                listOffsetPtsR[idx+1] = vecBisect;
                listOffsetPtsR[idx+2] = vecBisect;
            }
        }
    }

    // save vertex data
    listVx.resize(listOffsetPtsL.size()*2);
    listTx.resize(listVx.size()); k=0;
    for(size_t i=0; i < listOffsetPtsL.size(); i++)
    {   // left
        listVx[k] = listOffsetPtsL[i];
        listTx[k] = listOffsetTxL[i];   k++;
        // right
        listVx[k] = listOffsetPtsR[i];
        listTx[k] = listOffsetTxR[i];   k++;
    }

    // save length
    polylineLength = totalLength;
}
示例#25
0
    virtual void ProcessEvent( EFlowEvent event, SActivationInfo *pActInfo )
    {
        switch (event)
        {
        case eFE_Initialize:
            break;
        case eFE_Activate:
            IGameFramework* pGameFramework = gEnv->pGame->GetIGameFramework();

            if(IsPortActive(pActInfo, EIP_Cast))
            {
                // setup ray + optionally skip 1 entity
                ray_hit rayHit;
                static const float maxRayDist = 100.f;
                const unsigned int flags = rwi_stop_at_pierceable|rwi_colltype_any;
                IPhysicalEntity	*skipList[1];
                int skipCount = 0;
                IEntity* skipEntity = gEnv->pEntitySystem->GetEntity(GetPortEntityId(pActInfo, EIP_SkipEntity));
                if(skipEntity)
                {
                    skipList[0] = skipEntity->GetPhysics();
                    skipCount = 1;
                }

                Vec3 rayPos = GetPortVec3(pActInfo, EIP_RayPos);
                Vec3 rayDir = GetPortVec3(pActInfo, EIP_RayDir);

                // Check if the ray hits an entity
                if(gEnv->pSystem->GetIPhysicalWorld()->RayWorldIntersection(rayPos, rayDir * 100, ent_all, flags, &rayHit, 1, skipList, skipCount))
                {
                    int type = rayHit.pCollider->GetiForeignData();

                    if (type == PHYS_FOREIGN_ID_ENTITY)
                    {
                        IEntity* pEntity = (IEntity*)rayHit.pCollider->GetForeignData(PHYS_FOREIGN_ID_ENTITY);
                        IEntityRenderProxy* pRenderProxy = pEntity ? (IEntityRenderProxy*)pEntity->GetProxy(ENTITY_PROXY_RENDER) : 0;

                        // Get the renderproxy, and use it to check if the material is a DynTex, and get the UIElement if so
                        if(pRenderProxy)
                        {
                            IRenderNode *pRenderNode = pRenderProxy->GetRenderNode();
                            IMaterial* pMaterial = pRenderProxy->GetRenderMaterial();
                            SEfResTexture* texture = 0;
                            if(pMaterial && pMaterial->GetShaderItem().m_pShaderResources)
                                texture= pMaterial->GetShaderItem().m_pShaderResources->GetTexture(EFTT_DIFFUSE);
                            IUIElement* pElement = texture ? gEnv->pFlashUI->GetUIElementByInstanceStr(texture->m_Name) : 0;

                            if(pElement && pRenderNode)
                            {
                                int m_dynTexGeomSlot = 0;
                                IStatObj* pObj = pRenderNode->GetEntityStatObj(m_dynTexGeomSlot);

                                // result
                                bool hasHit = false;
                                Vec2 uv0, uv1, uv2;
                                Vec3 p0, p1, p2;
                                Vec3 hitpos;


                                // calculate ray dir
                                CCamera cam = gEnv->pRenderer->GetCamera();
                                if (pEntity->GetSlotFlags(m_dynTexGeomSlot) & ENTITY_SLOT_RENDER_NEAREST)
                                {
                                    ICVar *r_drawnearfov = gEnv->pConsole->GetCVar("r_DrawNearFoV");
                                    assert(r_drawnearfov);
                                    cam.SetFrustum(cam.GetViewSurfaceX(),cam.GetViewSurfaceZ(),DEG2RAD(r_drawnearfov->GetFVal()),cam.GetNearPlane(),cam.GetFarPlane(), cam.GetPixelAspectRatio());
                                }

                                Vec3 vPos0 = rayPos;
                                Vec3 vPos1 = rayPos + rayDir;

                                // translate into object space
                                const Matrix34 m = pEntity->GetWorldTM().GetInverted();
                                vPos0 = m * vPos0;
                                vPos1 = m * vPos1;

                                // walk through all sub objects
                                const int objCount = pObj->GetSubObjectCount();
                                for (int obj = 0; obj <= objCount && !hasHit; ++obj)
                                {
                                    Vec3 vP0, vP1;
                                    IStatObj* pSubObj = NULL;

                                    if (obj == objCount)
                                    {
                                        vP0 = vPos0;
                                        vP1 = vPos1;
                                        pSubObj = pObj;
                                    }
                                    else
                                    {
                                        IStatObj::SSubObject* pSub = pObj->GetSubObject(obj);
                                        const Matrix34 mm = pSub->tm.GetInverted();
                                        vP0 = mm * vPos0;
                                        vP1 = mm * vPos1;
                                        pSubObj = pSub->pStatObj;
                                    }

                                    IRenderMesh* pMesh = pSubObj ? pSubObj->GetRenderMesh() : NULL;
                                    if (pMesh)
                                    {
                                        const Ray ray(vP0, (vP1-vP0).GetNormalized() * maxRayDist);
                                        hasHit = RayIntersectMesh(pMesh, pMaterial, pElement, ray, hitpos, p0, p1, p2, uv0, uv1, uv2);
                                    }
                                }

                                // skip if not hit
                                if (!hasHit)
                                {
                                    ActivateOutput(pActInfo, EOP_Failed, 1);
                                    return;
                                }

                                // calculate vectors from hitpos to vertices p0, p1 and p2:
                                const Vec3 v0 = p0-hitpos;
                                const Vec3 v1 = p1-hitpos;
                                const Vec3 v2 = p2-hitpos;

                                // calculate factors
                                const float h = (p0-p1).Cross(p0-p2).GetLength();
                                const float f0 = v1.Cross(v2).GetLength() / h;
                                const float f1 = v2.Cross(v0).GetLength() / h;
                                const float f2 = v0.Cross(v1).GetLength() / h;

                                // find the uv corresponding to hitpos
                                Vec3 uv = uv0 * f0 + uv1 * f1 + uv2 * f2;

                                // translate to flash space
                                int x, y, width, height;
                                float aspect;
                                pElement->GetFlashPlayer()->GetViewport(x, y, width, height, aspect);
                                int iX = int_round(uv.x * (float)width);
                                int iY = int_round(uv.y * (float)height);

                                // call the function provided if it is present in the UIElement description
                                string funcName = GetPortString(pActInfo, EIP_CallFunction);
                                const SUIEventDesc* eventDesc = pElement->GetFunctionDesc(funcName);
                                if(eventDesc)
                                {
                                    SUIArguments arg;
                                    arg.AddArgument(iX);
                                    arg.AddArgument(iY);
                                    pElement->CallFunction(eventDesc->sName, arg);
                                }

                                ActivateOutput(pActInfo, EOP_Success, 1);
                            }
                        }
                    }
                }

                ActivateOutput(pActInfo, EOP_Failed, 1);
            }

            break;
        }
    }
示例#26
0
	bool Triangle::Intersect(const Ray& ray, Intersection& intersection) const
	{
		//
		// Moller–Trumbore intersection algorithm
		//

		Vec3 p = ray.direction.Cross(e2_);
		float det = e1_.Dot(p);

		// check determinant
		if (ray.refracted)
		{
			if (det > -Util::Eps)
			{
				// if det is close to 0 - ray lies in plane of triangle
				// if det is positive - ray comes from outside
				return false;
			}
		}
		else
		{
			if (det < Util::Eps)
			{
				// if det is close to 0 - ray lies in plane of triangle
				// if det is negative - ray comes from middle
				return false;
			}
		}

		// invert determinant
		float invDet = 1.0f / det;

		// get first barycentric coordinate
		Vec3 s = ray.origin - vertices_[0].coord;
		float u = invDet * s.Dot(p);

		// check first barycentric coordinate
		if ((u < 0.0f) || (u > 1.0f))
		{
			return false;
		}

		// get second barycentric coordinate
		Vec3 q = s.Cross(e1_);
		float v = invDet * ray.direction.Dot(q);

		// check second and third barycentric coordinates
		if ((v < 0.0f) || ((u + v) > 1.0f))
		{
			return false;
		}

		// at this stage we can compute t to find out where
		// the intersection point is on the line
		float t = invDet * e2_.Dot(q);

		// check intersection
		if (t < Util::Eps)
		{
			// this means that there is a line intersection
			// but not a ray intersection
			return false;
		}

		// ray intersection point
		Vec3 point = ray.origin + t * ray.direction;

		// normal
		intersection.normal = ((1.0f - u - v) * vertices_[0].normal + u * vertices_[1].normal + v * vertices_[2].normal).Normalize();

		// fill the intersection data
		intersection.point = std::move(point);
		// intersection.normal = n;
		intersection.distance = t;

		return true;
	}
void CMountedGunController::Update(EntityId mountedGunID, float frameTime)
{
    CRY_ASSERT_MESSAGE(m_pControlledPlayer, "Controlled player not initialized");

    CItem* pMountedGun = static_cast<CItem*>(gEnv->pGame->GetIGameFramework()->GetIItemSystem()->GetItem(mountedGunID));

    bool canUpdateMountedGun = (pMountedGun != NULL) && (pMountedGun->GetStats().mounted);

    if (canUpdateMountedGun)
        {
            IMovementController * pMovementController = m_pControlledPlayer->GetMovementController();
            assert(pMovementController);

            SMovementState info;
            pMovementController->GetMovementState(info);

            IEntity* pMountedGunEntity = pMountedGun->GetEntity();
            const Matrix34& lastMountedGunWorldTM = pMountedGunEntity->GetWorldTM();

            Vec3 desiredAimDirection = info.aimDirection.GetNormalized();

            // AI can switch directions too fast, prevent snapping
            if(!m_pControlledPlayer->IsPlayer())
                {
                    const Vec3 currentDir = lastMountedGunWorldTM.GetColumn1();
                    const float dot = clamp(currentDir.Dot(desiredAimDirection), -1.0f, 1.0f);
                    const float reqAngle = cry_acosf(dot);
                    const float maxRotSpeed = 2.0f;
                    const float maxAngle = frameTime * maxRotSpeed;
                    if(fabs(reqAngle) > maxAngle)
                        {
                            const Vec3 axis = currentDir.Cross(desiredAimDirection);
                            if(axis.GetLengthSquared() > 0.001f) // current dir and new dir are enough different
                                {
                                    desiredAimDirection = currentDir.GetRotated(axis.GetNormalized(),sgn(reqAngle)*maxAngle);
                                }
                        }
                }

            bool isUserClient = m_pControlledPlayer->IsClient();

            IEntity* pMountedGunParentEntity = pMountedGunEntity->GetParent();
            IVehicle *pVehicle = NULL;
            if(pMountedGunParentEntity && m_pControlledPlayer)
                pVehicle = m_pControlledPlayer->GetLinkedVehicle();

            CRecordingSystem* pRecordingSystem = g_pGame->GetRecordingSystem();

            //For client update always, for others only when there is notable change
            if (!pVehicle && (isUserClient || (!desiredAimDirection.IsEquivalent(lastMountedGunWorldTM.GetColumn1(), 0.003f))))
                {
                    Quat rotation = Quat::CreateRotationVDir(desiredAimDirection, 0.0f);
                    pMountedGunEntity->SetRotation(rotation);

                    if (isUserClient && pRecordingSystem)
                        {
                            // Only record the gun position if you're using the gun.
                            pRecordingSystem->OnMountedGunRotate(pMountedGunEntity, rotation);
                        }
                }

            const Vec3 vInitialAimDirection = GetMountDirection(pMountedGun, pMountedGunParentEntity);
            assert( vInitialAimDirection.IsUnit() );

            //Adjust gunner position and animations
            UpdateGunnerLocation(pMountedGun, pMountedGunParentEntity, vInitialAimDirection);

            const float aimrad = Ang3::CreateRadZ(Vec2(vInitialAimDirection),Vec2(-desiredAimDirection));
            const float pitchLimit = sin_tpl(DEG2RAD(30.0f));
            const float animHeight = fabs_tpl(clamp(desiredAimDirection.z * (float)__fres(pitchLimit), -1.0f, 1.0f));

            const float aimUp = (float)__fsel(-desiredAimDirection.z, 0.0f, animHeight);
            const float aimDown = (float)__fsel(desiredAimDirection.z, 0.0f, animHeight);

            if (pRecordingSystem)
                {
                    pRecordingSystem->OnMountedGunUpdate(m_pControlledPlayer, aimrad, aimUp, aimDown);
                }

            if(!m_pControlledPlayer->IsThirdPerson())
                {
                    UpdateFirstPersonAnimations(pMountedGun, desiredAimDirection);
                }

            if(m_pMovementAction)
                {
                    const float aimUpParam = aimUp;
                    const float aimDownParam = aimDown;
                    const float aimMovementParam = CalculateAnimationTime(aimrad);

                    m_pMovementAction->SetParam(MountedGunCRCs.aimUpParam, aimUpParam);
                    m_pMovementAction->SetParam(MountedGunCRCs.aimDownParam, aimDownParam);
                    m_pMovementAction->SetParam(MountedGunCRCs.aimMovementParam, aimMovementParam);
                }

            UpdateIKMounted(pMountedGun);
        }
}
示例#28
0
void CHUD::IndicateDamage(EntityId weaponId, Vec3 direction, bool onVehicle)
{
	Vec3 vlookingDirection = FORWARD_DIRECTION;
	CGameFlashAnimation* pAnim = NULL;

	CActor *pPlayerActor = static_cast<CActor *>(gEnv->pGame->GetIGameFramework()->GetClientActor());
	if(!pPlayerActor)
		return;

	if(IEntity *pEntity = gEnv->pEntitySystem->GetEntity(weaponId))
	{
		if(pEntity->GetClass() == CItem::sGaussRifleClass)
		{
			m_animRadarCompassStealth.Invoke("GaussHit");
			m_animPlayerStats.Invoke("GaussHit");
		}
	}

	IMovementController *pMovementController = NULL;

	float fFront = 0.0f;
	float fRight = 0.0f;

	if(!onVehicle)
	{
		if(!g_pGameCVars->hud_chDamageIndicator)
			return;
		pMovementController = pPlayerActor->GetMovementController();
		pAnim = m_pHUDCrosshair->GetFlashAnim();
	}
	else if(IVehicle *pVehicle = pPlayerActor->GetLinkedVehicle())
	{
		pMovementController = pVehicle->GetMovementController();
		pAnim = &(m_pHUDVehicleInterface->m_animStats);
	}

	if(pMovementController && pAnim)
	{
		SMovementState sMovementState;
		pMovementController->GetMovementState(sMovementState);
		vlookingDirection = sMovementState.eyeDirection;
	}
	else
		return;

	if(!onVehicle)
	{
		//we use a static/world damage indicator and add the view rotation to the indicator animation now
		fFront = -(Vec3(0,-1,0).Dot(direction));
		fRight = -(Vec3(-1, 0, 0).Dot(direction));
	}
	else
	{
		Vec3 vRightDir = vlookingDirection.Cross(Vec3(0,0,1));
		fFront = -vlookingDirection.Dot(direction);
		fRight = -vRightDir.Dot(direction);
	}

	if(fabsf(fFront) > 0.35f)
	{
		if(fFront > 0)
			pAnim->Invoke("setDamageDirection", 1);
		else
			pAnim->Invoke("setDamageDirection", 3);
	}
	if(fabsf(fRight) > 0.35f)
	{
		if(fRight > 0)
			pAnim->Invoke("setDamageDirection", 2);
		else
			pAnim->Invoke("setDamageDirection", 4);
	}
	if(fFront == 0.0f && fRight == 0.0f)
	{
		pAnim->Invoke("setDamageDirection", 1);
		pAnim->Invoke("setDamageDirection", 2);
		pAnim->Invoke("setDamageDirection", 3);
		pAnim->Invoke("setDamageDirection", 4);
	}

	m_fDamageIndicatorTimer = gEnv->pTimer->GetFrameStartTime().GetSeconds();
}