//------------------------------------------------------------------------
void CTracer::Reset(const Vec3 &pos, const Vec3 &dest)
{
	m_pos.zero();
	m_dest.zero();
	m_startingPos=pos;
	m_age=0.0f;
	m_lifeTime=1.5f;
	m_tracerFlags &= ~kTracerFlag_scaleToDistance;
	m_startFadeOutTime = 0.0f;
	m_slideFrac = 0.f;

	if (IEntity *pEntity=gEnv->pEntitySystem->GetEntity(m_entityId))
	{
		pEntity->FreeSlot(TRACER_GEOM_SLOT);
		pEntity->FreeSlot(TRACER_FX_SLOT);

		Vec3 dir = dest - pos;
		dir.Normalize();

		Matrix34 tm;
		
		tm.SetIdentity();

		if(!dir.IsZero())
		{
			tm = Matrix33::CreateRotationVDir(dir);
		}
		
		tm.AddTranslation(pos);
		pEntity->SetWorldTM(tm);
	}
}
bool CIntersectionAssistanceUnit::TestForIntersectionAtLocation(const eTestMethod testMethod, const Matrix34& wMat, EntityId testEntityId, EntityId ignoreEnt, QuatT& outAdjustedResult, const bool bCentreOnFocalEnt /* = false */, bool bRenderOnFail /* = true */, const int index /* = -1*/)
{
    // Build an OOBB that surrounds this entity, test for intersection between that and world
    IEntity* pEntity = gEnv->pEntitySystem->GetEntity(testEntityId);
    if(pEntity)
        {
            IPhysicalEntity* pPhysical = pEntity->GetPhysics();
            if(pPhysical)
                {
                    OBB entOBB;
                    AABB entAABB;
                    pEntity->GetLocalBounds(entAABB);
                    entOBB.SetOBBfromAABB(Quat(IDENTITY), entAABB);

                    // Do Primitive world intersection
                    primitives::box physBox;
                    physBox.bOriented = 1;

                    // LSpace
                    physBox.center = entOBB.c;
                    physBox.Basis = entOBB.m33;
                    physBox.size.x = entOBB.h.x;
                    physBox.size.y = entOBB.h.y;
                    physBox.size.z = entOBB.h.z;

                    // WSpace
                    physBox.center					= wMat.TransformPoint(physBox.center);
                    physBox.Basis					  *= Matrix33(wMat).GetInverted();

                    // Optional tweak - We can get away with a little bit of scaling down (if edges are slightly embedded the physics pushes them out easily)
                    physBox.size = physBox.size.scale(kPhysBoxScaleFactor);

                    // adjust
                    Vec3 vAdjustments(0.0f,0.0f,0.0f);
                    if(bCentreOnFocalEnt && m_focalEntityId)
                        {
                            Vec3 vDesiredPos = CalculateTargetAdjustPoint(pEntity, wMat, physBox.center);
                            vAdjustments = (vDesiredPos - physBox.center);
                            physBox.center += vAdjustments;
                        }

                    IEntity* pIgnoreEnt = gEnv->pEntitySystem->GetEntity(ignoreEnt);
                    IPhysicalEntity* pIgnorePhys = pIgnoreEnt ? pIgnoreEnt->GetPhysics() : NULL;

                    // Test
                    if(testMethod == eTM_Immediate
#ifndef _RELEASE
                            || g_pGameCVars->pl_pickAndThrow.intersectionAssistDebugEnabled >= 1
#endif // #ifndef _RELEASE
                      )
                        {
                            geom_contact *contacts;
                            intersection_params params;
                            float numHits = gEnv->pPhysicalWorld->PrimitiveWorldIntersection(primitives::box::type, &physBox, Vec3(ZERO),
                                            ent_static|ent_terrain, &contacts, 0,
                                            3, &params, 0, 0, &pIgnorePhys, pIgnorePhys ? 1 : 0);

                            // Debug
#ifndef _RELEASE
                            if(g_pGameCVars->pl_pickAndThrow.intersectionAssistDebugEnabled)
                                {

                                    const bool bIntersect = numHits <= 0.0f ? false : true;
                                    if(bRenderOnFail || !bIntersect)
                                        {
                                            const ColorB colorPositive = ColorB(16, 96, 16);
                                            const ColorB colorNegative = ColorB(128, 0, 0);
                                            const ColorB colorSelected = ColorB(0,255,0);

                                            if(numHits > 0.0f)
                                                {
                                                    gEnv->pRenderer->GetIRenderAuxGeom()->DrawSphere(contacts->pt, 0.1f, colorPositive);
                                                }

                                            OBB finalOBB;
                                            finalOBB.SetOBB(Matrix33(IDENTITY), physBox.size, Vec3(0.0f,0.0f,0.0f));
                                            Matrix34 drawMat = wMat;
                                            drawMat.AddTranslation(physBox.center - wMat.GetTranslation());
                                            if(index != -1 && index == m_currentBestIndex)
                                                {
                                                    gEnv->pRenderer->GetIRenderAuxGeom()->DrawOBB(finalOBB, drawMat, false, colorSelected, eBBD_Faceted);
                                                }
                                            else
                                                {
                                                    gEnv->pRenderer->GetIRenderAuxGeom()->DrawOBB(finalOBB, drawMat, false, bIntersect ? colorNegative : colorPositive, eBBD_Faceted);
                                                }

                                        }
                                }
#endif //#ifndef RELEASE

                            // If we performed an adjust, make sure we pass out the QuatT representing the FINAL ENTITY POSITION that passed/failed (not the phys box etc)
                            outAdjustedResult.t = wMat.GetTranslation() + vAdjustments;
                            outAdjustedResult.q = Quat(wMat);

#ifndef _RELEASE
                            // allow optional debug drawing of last known good positions by retaining non adjusted position
                            if(g_pGameCVars->pl_pickAndThrow.intersectionAssistDebugEnabled == 1)
                                {
                                    outAdjustedResult.t = wMat.GetTranslation();
                                }
#endif // #ifndef _RELEASE

                            return (numHits > 0.0f);
                        }
                    else
                        {
                            // QUEUE primitive intersection check
                            outAdjustedResult.t = wMat.GetTranslation() + vAdjustments;
                            outAdjustedResult.q = Quat(wMat);
                            CRY_ASSERT(index >= 0);
                            m_intersectionTester.DoCheck(index,physBox,outAdjustedResult,pIgnorePhys);
                            return false;
                        }
                }
        }

    return false;
}
示例#3
0
void CEntityObject::Render( CEntity* pEntity,SRendParams &rParams,int nRndFlags,CRenderProxy* pRenderProxy, const SRenderingPassInfo &passInfo )
{
	if (!bWorldTMValid)
	{
		UpdateWorldTM(pEntity);
	}

	// Override with custom slot material.
	IMaterial* pPrevMtl = rParams.pMaterial;
	if (pMaterial)
		rParams.pMaterial = pMaterial;

	int32 nOldObjectFlags = rParams.dwFObjFlags;
	rParams.dwFObjFlags |= dwFObjFlags;


	if (flags & ENTITY_SLOT_RENDER_AFTER_POSTPROCESSING)
	{
		rParams.dwFObjFlags |= FOB_RENDER_AFTER_POSTPROCESSING;
	}

#ifdef SEG_WORLD
	rParams.nCustomFlags |= (1 << (COB_SW_SHIFT + pEntity->GetSwObjDebugFlag()));
#endif // SEG_WORLD

	//////////////////////////////////////////////////////////////////////////

	rParams.pInstance = this;

	const bool bIsInCameraSpace = (flags & ENTITY_SLOT_RENDER_NEAREST) != 0;

	// Draw static object.
	if (pStatObj)
	{
		rParams.pMatrix      = &m_worldTM;
		rParams.dwFObjFlags |= FOB_TRANS_MASK;
		rParams.pFoliage     = pFoliage;

		rParams.nSubObjHideMask = nSubObjHideMask;

		// make sure object motion blur can be applied to this object
		if (bObjectMoved)
		{
			rParams.dwFObjFlags |= FOB_DYNAMIC_OBJECT;
			bObjectMoved         = false;
		}

		Matrix34 entityTM;
		if (bIsInCameraSpace)
		{
			rParams.pMatrix = &entityTM;
			entityTM        = m_worldTM;

			// Camera space
			if (m_pCameraSpacePos)
			{
				// Use camera space relative position
				entityTM.SetTranslation(*m_pCameraSpacePos);
			}
			else
			{
				// We don't have camera space relative position, so calculate it out from world space
				// (This will not have the precision advantages of camera space rendering)
				entityTM.AddTranslation(-gEnv->pSystem->GetViewCamera().GetPosition());
			}
		}

		if (rParams.pMatrix->IsValid())
			pStatObj->Render( rParams, passInfo );
		else
			EntityWarning("CEntityObject::Render: Invalid world matrix: %s", pEntity->GetEntityTextDescription());
	}
	else if (pCharacter)
	{
		QuatTS   Offset;
		Matrix34 PhysLocation(pEntity->GetWorldTM());
		if (m_pXForm)
			Offset = QuatTS(m_pXForm->localTM);
		else
		{
			//CRY_FIXME(03,12,2009,"Animation & Rendering of entities needs to be re-written to avoid derivation of local offset due to float inaccuracy - Richard Semmens");

			if (!Matrix34::IsEquivalent(PhysLocation,m_worldTM))
			{
				Matrix34 invPhysLocation = PhysLocation.GetInverted();

				Matrix34 matOffset = invPhysLocation * m_worldTM;

				Offset = QuatTS(matOffset);
			}
			else
			{
				Offset.SetIdentity();
			}
		}

		if (bIsInCameraSpace)
		{
			// Camera space
			if (m_pCameraSpacePos)
			{
				// Use camera space relative position
				const Matrix33 camRot = Matrix33(gEnv->pSystem->GetViewCamera().GetViewMatrix());
				PhysLocation.SetTranslation(*m_pCameraSpacePos * camRot);
			}
			else
			{
				// We don't have camera space relative position, so calculate it out from world space
				// (This will not have the precision advantages of camera space rendering)
				PhysLocation.AddTranslation(-gEnv->pSystem->GetViewCamera().GetPosition());
			}
			Offset.SetIdentity();
		}

		rParams.pMatrix = &PhysLocation;
		//rParams.pInstance = pCharacter;

		// Disable hand-placed (static) decals on characters
		rParams.dwFObjFlags |= FOB_DYNAMIC_OBJECT;

		pCharacter->Render(rParams, Offset, passInfo);

		const uint32 renderProxyFlags = pRenderProxy->GetFlags();
		if (!passInfo.IsShadowPass() || (renderProxyFlags & CRenderProxy::FLAG_ANIMATE_OFFSCREEN_SHADOW))
		{
			// If We render character, make sure it is also gets animation activated.
			if (!pEntity->m_bInActiveList)
				pEntity->ActivateForNumUpdates(8);
		}
	}
	else if (pChildRenderNode)
	{
		rParams.pMatrix = &m_worldTM;
		//rParams.pInstance = pChildRenderNode;

		pChildRenderNode->m_dwRndFlags = nRndFlags;
		pChildRenderNode->Render( rParams, passInfo );
	}

	rParams.pMaterial   = pPrevMtl;
	rParams.dwFObjFlags = nOldObjectFlags;

	if (!passInfo.IsShadowPass())   // Should also ignore rendering into the recursion.
	{
		if (pFoliage)
		{
			pFoliage->SetFlags(pFoliage->GetFlags() & ~IFoliage::FLAG_FROZEN | -(int)(rParams.nMaterialLayers & MTL_LAYER_FROZEN) & IFoliage::FLAG_FROZEN);
			static ICVar* g_pWindActivationDist = gEnv->pConsole->GetCVar("e_FoliageWindActivationDist");
			float         maxdist               = g_pWindActivationDist ? g_pWindActivationDist->GetFVal() : 0.0f;
			Vec3          pos                   = m_worldTM.GetTranslation();
			if (pStatObj && (gEnv->pSystem->GetViewCamera().GetPosition() - pos).len2() < sqr(maxdist) && gEnv->p3DEngine->GetWind(AABB(pos),false).len2() > 101.0f)
				pStatObj->PhysicalizeFoliage(pEntity->GetPhysics(),m_worldTM,pFoliage,0,4);
		}
	}
}
示例#4
0
//--------------------------------------------------------------------------------------------------
// Name: CalculateGlassBounds
// Desc: Calculates glass bounds from physics geometry
//--------------------------------------------------------------------------------------------------
void CBreakableGlassSystem::CalculateGlassBounds(const phys_geometry* const pPhysGeom, Vec3& size, Matrix34& matrix)
{
	// Find thinnest axis of physics geometry
	primitives::box bbox;
	pPhysGeom->pGeom->GetBBox(&bbox);

	Matrix33 basis = bbox.Basis.T();
	Vec3 halfSize = bbox.size;
	Vec3 center = bbox.center;

	const uint thinAxis = idxmin3(&halfSize.x);

	// Need to rotate so Z is our thin axis
	if (thinAxis < 2)
	{
		float tempSize;
		Matrix33 tempMat;
		tempMat.SetIdentity();

		// Calculate the rotation based on current facing dir
		const Vec3 axes[2] =
		{
			Vec3Constants<float>::fVec3_OneX,
			Vec3Constants<float>::fVec3_OneY
		};

		const Vec3& thinRow = bbox.Basis.GetRow(thinAxis);
		const Vec3 localAxis = bbox.Basis.TransformVector(axes[thinAxis]);
		float rot = (thinRow.Dot(localAxis) >= 0.0f) ? -gf_PI*0.5f : gf_PI*0.5f;

		if (thinAxis == 0)
		{
			tempSize = halfSize.x;
			halfSize.x = halfSize.z;

			tempMat.SetRotationY(rot);
		}
		else
		{
			tempSize = halfSize.y;
			halfSize.y = halfSize.z;

			tempMat.SetRotationX(rot);
		}

		// Apply rotation to matrix and vectors
		basis = basis * tempMat;
		halfSize.z = tempSize;
	}

	// Assert minimum thickness
	const float halfMinThickness = 0.004f;
	halfSize.z = max(halfSize.z, halfMinThickness);

	size = halfSize * 2.0f;

	// Calculate locally offset bounds
	matrix.SetIdentity();
	matrix.SetTranslation(-halfSize);

	matrix = basis * matrix;

	matrix.AddTranslation(center);
}//------------------------------------------------------------------------------------------------- 
示例#5
0
//----------------------------------------------------
void CRocketLauncher::UpdateTPLaser(float frameTime)
{
	m_lastUpdate -= frameTime;

	bool allowUpdate = true;
	if(m_lastUpdate<=0.0f)
		m_lastUpdate = m_Timeout;
	else
		allowUpdate = false;

	const CCamera& camera = gEnv->pRenderer->GetCamera();

	//If character not visible, laser is not correctly updated
	if(CActor* pOwner = GetOwnerActor())
	{
		ICharacterInstance* pCharacter = pOwner->GetEntity()->GetCharacter(0);
		if(pCharacter && !pCharacter->IsCharacterVisible())
			return;
	}

	Vec3   offset(-0.06f,0.28f,0.115f); //To match scope position in TP LAW model
	Vec3   pos = GetEntity()->GetWorldTM().TransformPoint(offset);
	Vec3   dir = GetEntity()->GetWorldRotation().GetColumn1();

	Vec3 hitPos(0,0,0);
	float laserLength = 0.0f;

	if(allowUpdate)
	{
		IPhysicalEntity* pSkipEntity = NULL;
		if(GetOwner())
			pSkipEntity = GetOwner()->GetPhysics();

		const float range = m_LaserRangeTP;

		// Use the same flags as the AI system uses for visibility.
		const int objects = ent_terrain|ent_static|ent_rigid|ent_sleeping_rigid|ent_independent; //ent_living;
		const int flags = (geom_colltype_ray << rwi_colltype_bit) | rwi_colltype_any | (10 & rwi_pierceability_mask) | (geom_colltype14 << rwi_colltype_bit);

		ray_hit hit;
		if (gEnv->pPhysicalWorld->RayWorldIntersection(pos, dir*range, objects, flags,
			&hit, 1, &pSkipEntity, pSkipEntity ? 1 : 0))
		{
			laserLength = hit.dist;
			m_lastLaserHitPt = hit.pt;
			m_lastLaserHitSolid = true;
		}
		else
		{
			m_lastLaserHitSolid = false;
			m_lastLaserHitPt = pos + dir * range;
			laserLength = range + 0.1f;
		}

		// Hit near plane
		if (dir.Dot(camera.GetViewdir()) < 0.0f)
		{
			Plane nearPlane;
			nearPlane.SetPlane(camera.GetViewdir(), camera.GetPosition());
			nearPlane.d -= camera.GetNearPlane()+0.15f;
			Ray ray(pos, dir);
			Vec3 out;
			m_lastLaserHitViewPlane = false;
			if (Intersect::Ray_Plane(ray, nearPlane, out))
			{
				float dist = Distance::Point_Point(pos, out);
				if (dist < laserLength)
				{
					laserLength = dist;
					m_lastLaserHitPt = out;
					m_lastLaserHitSolid = true;
					m_lastLaserHitViewPlane = true;
				}
			}
		}

		hitPos = m_lastLaserHitPt;
	}
	else
	{
		laserLength = Distance::Point_Point(m_lastLaserHitPt, pos);
		hitPos = pos + dir * laserLength;
	}

	if (m_smoothLaserLength < 0.0f)
		m_smoothLaserLength = laserLength;
	else
	{
		if (laserLength < m_smoothLaserLength)
			m_smoothLaserLength = laserLength;
		else
			m_smoothLaserLength += (laserLength - m_smoothLaserLength) * min(1.0f, 10.0f * frameTime);
	}

	const float assetLength = 2.0f;
	m_smoothLaserLength = CLAMP(m_smoothLaserLength,0.01f,m_LaserRangeTP);
	float scale = m_smoothLaserLength / assetLength; 

	// Scale the laser based on the distance.
	Matrix34 scl;
	scl.SetIdentity();
	scl.SetScale(Vec3(1,scale,1));
	scl.SetTranslation(offset);
	GetEntity()->SetSlotLocalTM( eIGS_Aux1, scl);

	if (m_dotEffectSlot >= 0)
	{
		if (m_lastLaserHitSolid)
		{
			Matrix34 dotMatrix = Matrix34::CreateTranslationMat(Vec3(0,m_smoothLaserLength,0));
			dotMatrix.AddTranslation(offset);
			if(m_lastLaserHitViewPlane)
				dotMatrix.Scale(Vec3(0.2f,0.2f,0.2f));
			GetEntity()->SetSlotLocalTM(m_dotEffectSlot,dotMatrix);
		}
		else
		{
			Matrix34 scaleMatrix;
			scaleMatrix.SetIdentity();
			scaleMatrix.SetScale(Vec3(0.001f,0.001f,0.001f));
			GetEntity()->SetSlotLocalTM(m_dotEffectSlot, scaleMatrix);
		}
	}
}