Exemplo n.º 1
0
//------------------------------------------------------------------------
const Matrix33 &CItem::GetSlotHelperRotation(int slot, const char *helper, bool worldSpace, bool relative)
{
	static Matrix33 rotation;
	rotation.SetIdentity();

	IEntity* pEntity = GetEntity();
	if(!pEntity)
		return rotation;

	SEntitySlotInfo info;
	if (pEntity->GetSlotInfo(slot, info))
	{
    if (info.pStatObj)
    {
      IStatObj *pStatObj = info.pStatObj;
      rotation = Matrix33(pStatObj->GetHelperTM(helper));
      rotation.OrthonormalizeFast();
      rotation = Matrix33(GetEntity()->GetSlotLocalTM(slot, false))*rotation;        
    }
		else if (info.pCharacter)
		{
			ICharacterInstance *pCharacter = info.pCharacter;
			if(!pCharacter)
				return rotation;

			IAttachment* pAttachment = pCharacter->GetIAttachmentManager()->GetInterfaceByName(helper);
			if(pAttachment)
			{
				rotation = Matrix33(worldSpace ? pAttachment->GetAttWorldAbsolute().q : pAttachment->GetAttModelRelative().q);
				return rotation;
			}
			else
			{
				ICharacterModelSkeleton* pICharacterModelSkeleton = pCharacter->GetICharacterModel()->GetICharacterModelSkeleton();
				ISkeletonPose* pSkeletonPose = pCharacter->GetISkeletonPose();
				int16 id = pICharacterModelSkeleton->GetJointIDByName(helper);
				if (id > -1)
				{
					rotation = relative ? Matrix33(pSkeletonPose->GetRelJointByID(id).q) : Matrix33(pSkeletonPose->GetAbsJointByID(id).q);
				}
			}

			if (!relative)
			{
				rotation = Matrix33(pEntity->GetSlotLocalTM(slot, false)) * rotation;
			}
		}    
	}

	if (worldSpace)
	{
		rotation = Matrix33(pEntity->GetWorldTM()) * rotation;
	}

	return rotation;
}
Exemplo n.º 2
0
//------------------------------------------------------------------------
const Matrix33 &CItem::GetSlotHelperRotation(int slot, const char *helper, bool worldSpace, bool relative)
{
	// if mounted force the slot to be 1st person
	if(m_stats.mounted)
		slot=eIGS_FirstPerson;

	static Matrix33 rotation;
	rotation.SetIdentity();

	IEntity *pEntity = GetEntity();

	if(!pEntity)
		return rotation;

	SEntitySlotInfo info;

	if(pEntity->GetSlotInfo(slot, info))
	{
		if(info.pStatObj)
		{
			IStatObj *pStatObj = info.pStatObj;
			rotation = Matrix33(pStatObj->GetHelperTM(helper));
			rotation.OrthonormalizeFast();
			rotation = Matrix33(GetEntity()->GetSlotLocalTM(slot, false))*rotation;
		}
		else if(info.pCharacter)
		{
			ICharacterInstance *pCharacter = info.pCharacter;

			if(!pCharacter)
				return rotation;

			int16 id = pCharacter->GetISkeletonPose()->GetJointIDByName(helper);

			//	if (id > -1) rotation = Matrix33(pCharacter->GetISkeleton()->GetAbsJMatrixByID(id));
			if(id > -1)
			{
				if(relative)
					rotation = Matrix33(pCharacter->GetISkeletonPose()->GetRelJointByID(id).q);
				else
					rotation = Matrix33(pCharacter->GetISkeletonPose()->GetAbsJointByID(id).q);
			}

			if(!relative)
				rotation = Matrix33(pEntity->GetSlotLocalTM(slot, false))*rotation;
		}
	}

	if(worldSpace)
		rotation=Matrix33(pEntity->GetWorldTM())*rotation;

	return rotation;
}
Exemplo n.º 3
0
//------------------------------------------------------------------
void CLam::UpdateTPLaser(float frameTime, CItem* parent)
{
    FUNCTION_PROFILER(GetISystem(), PROFILE_GAME);

    const int frameId = gEnv->pRenderer->GetFrameID();

    if (s_lastUpdateFrameId != frameId)
    {
        // Check how many LAMs to update this frame.
        float dt = frameTime; // + s_laserUpdateTimeError;

        const int n = s_lasers.size();

        int nActive = 0;
        for (int i = 0; i < n; ++i)
        {
            if (!s_lasers[i]->IsLaserActivated() && !s_lasers[i]->IsLightActivated())
                continue;
            nActive++;
        }

        float updatedPerSecond = (nActive / LASER_UPDATE_TIME) + s_laserUpdateTimeError;
        int updateCount = (int)floorf(updatedPerSecond * dt);
        if(dt==0.0f)
            s_laserUpdateTimeError = 0.0f;
        else
            s_laserUpdateTimeError = updatedPerSecond - updateCount/dt;

        s_curLaser %= n;
        for (int i = 0, j = 0; i < n && j < updateCount ; ++i)
        {
            s_curLaser = (s_curLaser + 1) % n;
            if (!s_lasers[s_curLaser]->IsLaserActivated() && !s_lasers[s_curLaser]->IsLightActivated())
                continue;
            s_lasers[s_curLaser]->SetAllowUpdate();
            ++j;
        }

        s_lastUpdateFrameId = frameId;
    }

    IEntity* pRootEnt = GetEntity();
    if (!pRootEnt)
        return;

    IEntity *pLaserEntity = m_pEntitySystem->GetEntity(m_pLaserEntityId);
//	if(!pLaserEntity)
//		return;

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

    Vec3   lamPos = pRootEnt->GetWorldPos(); //pLaserEntity->GetParent()->GetWorldPos();
    Vec3   dir = pRootEnt->GetWorldRotation().GetColumn1(); //pLaserEntity->GetParent()->GetWorldRotation().GetColumn1();

    bool charNotVisible = false;

    float  dsg1Scale = 1.0f;

    //If character not visible, laser is not correctly updated
    if(parent)
    {
        if(CActor* pOwner = parent->GetOwnerActor())
        {
            ICharacterInstance* pCharacter = pOwner->GetEntity()->GetCharacter(0);
            if(pCharacter && !pCharacter->IsCharacterVisible())
                charNotVisible = true;
        }
        if(parent->GetEntity()->GetClass()==CItem::sDSG1Class)
            dsg1Scale = 3.0f;
    }

//	if (!pLaserEntity->GetParent())
//		return;

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

    // HACK??: Use player movement controller locations, or else the laser
    // pops all over the place when character out of the screen.
    CActor *pActor = parent->GetOwnerActor();
    if (pActor && (!pActor->IsPlayer() || charNotVisible))
    {
        if (IMovementController* pMC = pActor->GetMovementController())
        {
            SMovementState state;
            pMC->GetMovementState(state);
            if(!charNotVisible)
                lamPos = state.weaponPosition;
            else
            {
                float oldZPos = lamPos.z;
                lamPos = state.weaponPosition;
                if(m_lastZPos>0.0f)
                    lamPos.z = m_lastZPos; //Stabilize somehow z position (even if not accurate)
                else
                    lamPos.z = oldZPos;
            }
            const float angleMin = DEG2RAD(3.0f);
            const float angleMax = DEG2RAD(7.0f);
            const float thr = cosf(angleMax);
            float dot = dir.Dot(state.aimDirection);
            if (dot > thr)
            {
                float a = acos_tpl(dot);
                float u = 1.0f - clamp((a - angleMin) / (angleMax - angleMin), 0.0f, 1.0f);
                dir = dir + u * (state.aimDirection - dir);
                dir.Normalize();
            }
        }
    }

    if(!charNotVisible)
        m_lastZPos = lamPos.z;

    lamPos += (dir*0.10f);

    if (m_allowUpdate)
    {
        m_allowUpdate = false;

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

        const float range = m_lamparams.laser_range[eIGS_ThirdPerson]*dsg1Scale;

        // Use the same flags as the AI system uses for visbility.
        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(lamPos, 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 = lamPos + 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(lamPos, dir);
            Vec3 out;
            m_lastLaserHitViewPlane = false;
            if (Intersect::Ray_Plane(ray, nearPlane, out))
            {
                float dist = Distance::Point_Point(lamPos, 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, lamPos);
        hitPos = lamPos + 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);
    }

    float laserAIRange = 0.0f;
    if (m_laserActivated && pLaserEntity)
    {
        // Orient the laser towards the point point.
        Matrix34 parentTMInv;
        parentTMInv = pRootEnt->GetWorldTM().GetInverted();

        Vec3 localDir = parentTMInv.TransformPoint(hitPos);
        float finalLaserLen = localDir.NormalizeSafe();
        Matrix33 rot;
        rot.SetIdentity();
        rot.SetRotationVDir(localDir);
        pLaserEntity->SetLocalTM(rot);

        laserAIRange = finalLaserLen;

        const float assetLength = 2.0f;
        finalLaserLen = CLAMP(finalLaserLen,0.01f,m_lamparams.laser_max_len*dsg1Scale);
        float scale = finalLaserLen / assetLength;

        // Scale the laser based on the distance.
        if (m_laserEffectSlot >= 0)
        {
            Matrix33 scl;
            scl.SetIdentity();
            scl.SetScale(Vec3(1,scale,1));
            pLaserEntity->SetSlotLocalTM(m_laserEffectSlot, scl);
        }

        if (m_dotEffectSlot >= 0)
        {
            if (m_lastLaserHitSolid)
            {
                Matrix34 mt = Matrix34::CreateTranslationMat(Vec3(0,finalLaserLen,0));
                if(m_lastLaserHitViewPlane)
                    mt.Scale(Vec3(0.2f,0.2f,0.2f));
                pLaserEntity->SetSlotLocalTM(m_dotEffectSlot, mt);
            }
            else
            {
                Matrix34 scaleMatrix;
                scaleMatrix.SetIdentity();
                scaleMatrix.SetScale(Vec3(0.001f,0.001f,0.001f));
                pLaserEntity->SetSlotLocalTM(m_dotEffectSlot, scaleMatrix);
            }
        }
    }

    float lightAIRange = 0.0f;
    if (m_lightActivated)
    {
        float range = clamp(m_smoothLaserLength, 0.5f, m_lamparams.light_range[eIGS_ThirdPerson]);
        lightAIRange = range * 1.5f;

        if (m_lightID[eIGS_ThirdPerson] && m_smoothLaserLength > 0.0f)
        {
            CItem* pLightEffect = this;
            if (IItem *pOwnerItem = m_pItemSystem->GetItem(GetParentId()))
                pLightEffect = (CItem *)pOwnerItem;
            pLightEffect->SetLightRadius(range, m_lightID[eIGS_ThirdPerson]);
        }
    }


    if (laserAIRange > 0.0001f || lightAIRange > 0.0001f)
        UpdateAILightAndLaser(lamPos, dir, lightAIRange, m_lamparams.light_fov[eIGS_ThirdPerson], laserAIRange);

}
Exemplo n.º 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);
}//-------------------------------------------------------------------------------------------------