void CGameVolume_Water::CreatePhysicsArea(const uint32 segmentIndex, const Matrix34& baseMatrix, const Vec3* pVertices, uint32 vertexCount, const bool isRiver, const float streamSpeed)
{
	//Destroy previous physics if any
	if(segmentIndex == 0)
	{
		DestroyPhysicsAreas();
	}

	SWaterSegment& segment = m_segments[segmentIndex];

	IWaterVolumeRenderNode* pWaterRenderNode = segment.m_pWaterRenderNode;
	Vec3 waterFlow(ZERO);

	CRY_ASSERT (segment.m_pWaterArea == NULL);
	CRY_ASSERT (pWaterRenderNode != NULL);

	pWaterRenderNode->SetMatrix( Matrix34::CreateIdentity() ); 
	segment.m_pWaterArea = pWaterRenderNode->SetAndCreatePhysicsArea( &pVertices[0], vertexCount );

	IPhysicalEntity* pWaterArea = segment.m_pWaterArea;
	if( pWaterArea )
	{
		const Quat entityWorldRot = Quat(baseMatrix);

		pe_status_pos posStatus;
		pWaterArea->GetStatus( &posStatus );

		const Vec3 areaPosition = baseMatrix.GetTranslation() + ((entityWorldRot * posStatus.pos) - posStatus.pos);

		pe_params_pos position;
		position.pos = areaPosition;
		position.q = entityWorldRot;
		pWaterArea->SetParams( &position);

		pe_params_buoyancy pb;
		pb.waterPlane.n = entityWorldRot * Vec3( 0, 0, 1 );
		pb.waterPlane.origin = areaPosition;

		if(isRiver)
		{
			int i = segmentIndex;
			int j = vertexCount - 1 - segmentIndex;
			pb.waterFlow = ((pVertices[1]-pVertices[0]).GetNormalized() + (pVertices[2]-pVertices[3]).GetNormalized()) / 2.f * streamSpeed;
		}
		pWaterArea->SetParams( &pb);

		pe_params_foreign_data pfd;
		pfd.pForeignData = pWaterRenderNode;
		pfd.iForeignData = PHYS_FOREIGN_ID_WATERVOLUME;
		pfd.iForeignFlags = 0;
		pWaterArea->SetParams(&pfd);

		segment.m_physicsLocalAreaCenter = posStatus.pos;
	}
}
//------------------------------------------------------------------------
void CVehicleSeatActionRotateTurret::Serialize(TSerialize ser, EEntityAspects aspects)
{
	// MR: for network, only turret parts are serialized
	// for savegame, all parts are serialized (by CVehicle)
	if (ser.GetSerializationTarget() == eST_Network)
	{
		for (int i = 0; i < eVTRT_NumRotationTypes; ++i)
		{
			if (m_rotations[i].m_pPart)
			{
				m_rotations[i].m_pPart->Serialize(ser, aspects);
			}
		}
	}
	else
	{
		// save rotation details
		CryFixedStringT<16> tag;
		for (int i = 0; i < eVTRT_NumRotationTypes; ++i)
		{
			if (m_rotations[i].m_pPart)
			{
				Quat     q;
				Matrix34 currentTM = m_rotations[i].m_pPart->GetLocalBaseTM();
				if (ser.IsWriting())
					q = Quat(currentTM);

				tag = (i == eVTRT_Pitch) ? "rotation_pitch" : "rotation_yaw";
				ser.Value(tag.c_str(), q, 'ori1');

				if (ser.IsReading())
				{
					Matrix34 newTM(q);
					newTM.SetTranslation(currentTM.GetTranslation());
					m_rotations[i].m_pPart->SetLocalBaseTM(newTM);
					m_rotations[i].m_orientation.Set(q);
				}
			}
		}
	}
}
Example #3
0
//-----------------------------------------------------
void CThrow::ThrowLivingEntity(IEntity* pEntity, IPhysicalEntity* pPE)
{
	Vec3 hit = GetProbableHit(WEAPON_HIT_RANGE);
	Vec3 pos = GetFiringPos(hit);
	Vec3 dir = ApplySpread(GetFiringDir(hit, pos), GetSpread());
	Vec3 vel = GetFiringVelocity(dir);

	CPlayer *pPlayer = static_cast<CPlayer*>(m_pWeapon->GetOwnerActor());
	if(pPlayer)
	{
		float speed = 8.0f;
		dir.Normalize();

		if(CheckForIntersections(pPE,dir))
		{
			Matrix34 newTM = pEntity->GetWorldTM();
			newTM.SetTranslation(newTM.GetTranslation()-(dir*0.6f));
			pEntity->SetWorldTM(newTM,ENTITY_XFORM_POS);
		}

		{
			pe_action_set_velocity asv;
			asv.v = (dir*speed)+vel;
			pPE->Action(&asv); 
			// [anton] use thread safe=1 (immediate) if the character is still a living entity at this stage, 
			//   but will be ragdollized during the same frame

			pe_params_articulated_body pab;
			pab.bCheckCollisions = 1;	// was set to 0 while carrying
			pPE->SetParams(&pab);
		}		

		// Report throw to AI system.
		if (pPlayer->GetEntity() && pPlayer->GetEntity()->GetAI())
		{
			SAIEVENT AIevent;
			AIevent.targetId = pEntity->GetId();
			pPlayer->GetEntity()->GetAI()->Event(AIEVENT_PLAYER_STUNT_THROW_NPC, &AIevent);
		}
	}
}
Example #4
0
//------------------------------------------------------------------------
void CItem::SetCharacterAttachmentWorldTM(int slot, const char *name, const Matrix34 &tm)
{
	ICharacterInstance *pCharacter = GetEntity()->GetCharacter(slot);
	if (!pCharacter)
		return;

	IAttachmentManager *pAttachmentManager = pCharacter->GetIAttachmentManager();
	IAttachment *pAttachment = pAttachmentManager->GetInterfaceByName(name);

	if (!pAttachment)
	{
		GameWarning("Item '%s' trying to set world TM on attachment '%s' which does not exist!", GetEntity()->GetName(), name);
		return;
	}

//	Matrix34 boneWorldMatrix = GetEntity()->GetSlotWorldTM(slot) *	pCharacter->GetISkeleton()->GetAbsJMatrixByID(pAttachment->GetBoneID());
	Matrix34 boneWorldMatrix = GetEntity()->GetSlotWorldTM(slot) *	Matrix34(pCharacter->GetISkeletonPose()->GetAbsJointByID(pAttachment->GetBoneID()) );

	Matrix34 localAttachmentMatrix = (boneWorldMatrix.GetInverted()*tm);
	pAttachment->SetAttRelativeDefault(QuatT(localAttachmentMatrix));
}
//------------------------------------------------------------------------
void CVehicleHelper::GetReflectedWorldTM(Matrix34 &reflectedWorldTM) const
{
	FUNCTION_PROFILER( gEnv->pSystem, PROFILE_ACTION );

	Matrix34 tempMatrix = m_localTM;
	tempMatrix.m03 = -tempMatrix.m03;	// negate x coord of translation

	const Matrix34& partWorldTM = m_pParentPart->GetWorldTM();

	reflectedWorldTM = Matrix34(Matrix33(partWorldTM) * Matrix33(tempMatrix));
	reflectedWorldTM.SetTranslation((partWorldTM * tempMatrix).GetTranslation());
}
//------------------------------------------------------------------------
void CTracer::SetEffect(const char *name, float scale)
{
	IParticleEffect *pEffect = gEnv->pParticleManager->FindEffect(name);

	if (!pEffect)
	{
		return;
	}

	if (IEntity *pEntity = gEnv->pEntitySystem->GetEntity(m_entityId))
	{
		int slot = pEntity->LoadParticleEmitter(TRACER_FX_SLOT, pEffect, 0, true);

		if (scale != 1.0f)
		{
			Matrix34 tm = Matrix34::CreateIdentity();
			tm.Scale(Vec3(scale, scale, scale));
			pEntity->SetSlotLocalTM(slot, tm);
		}
	}
}
    bool CCoherentInputEventListener::TraceMouse( int& outX, int& outY, CCoherentViewListener*& pViewListener )
    {
        if ( gCoherentUISystem == nullptr )
        {
            return false;
        }

        CCamera& camera = gEnv->pSystem->GetViewCamera();
        int vpWidth = gEnv->pRenderer->GetWidth();
        int vpHeight = gEnv->pRenderer->GetHeight();
        float proj22 = 1.0f / cry_tanf( camera.GetFov() / 2.0f );
        float proj11 = proj22 / camera.GetProjRatio();
        float viewX = ( ( ( 2.0f * ( float )GetMouseX() ) / vpWidth ) - 1.0f ) / proj11;
        float viewY = ( ( ( -2.0f * ( float )GetMouseY() ) / vpHeight ) + 1.0f ) / proj22;
        Matrix34 invView = camera.GetMatrix();
        Vec3 dir = invView.TransformVector( Vec3( viewX, 1.0f, viewY ) ); // Z is up

        Vec3 origin = camera.GetPosition();

        return gCoherentUISystem->RaycastClosestViewListenersGeometry( origin, dir, outX, outY, pViewListener );
    }
void CVehiclePartWaterRipplesGenerator::Update(const float frameTime)
{
    //IVehicleMovement* pMovement = m_pVehicle->GetMovement();
    const SVehicleStatus& status = m_pVehicle->GetStatus();

    const bool movingFastEnough = (status.speed > m_minMovementSpeed);
    if (movingFastEnough)
    {
        const Matrix34 vehicleWorldTM = m_pVehicle->GetEntity()->GetWorldTM();

        // Check if moving backwards...
        if (m_onlyMovingForward)
        {
            const float dotProduct  = vehicleWorldTM.GetColumn1().Dot((status.vel / status.speed));
            if (dotProduct < 0.0f)
                return;
        }

        gEnv->pRenderer->EF_AddWaterSimHit( vehicleWorldTM.TransformPoint( m_localOffset ), m_waterRipplesScale, m_waterRipplesStrength );
    }
}
void CGameVolume_Water::DebugDrawVolume()
{
	IGameVolumes::VolumeInfo volumeInfo;
	if (GetVolumeInfoForEntity(GetEntityId(), volumeInfo) == false)
		return;

	if (volumeInfo.verticesCount < 3)
		return;

	const Matrix34 worldTM = GetEntity()->GetWorldTM();
	const Vec3 depthOffset = worldTM.GetColumn2().GetNormalized() * - m_volumeDepth;

	IRenderAuxGeom* pRenderAux = gEnv->pRenderer->GetIRenderAuxGeom();
	for (uint32 i = 0; i < volumeInfo.verticesCount - 1; ++i)
	{
		const Vec3 point1 = worldTM.TransformPoint(volumeInfo.pVertices[i]);
		const Vec3 point2 = worldTM.TransformPoint(volumeInfo.pVertices[i + 1]);

		pRenderAux->DrawLine( point1, Col_SlateBlue, point1 + depthOffset, Col_SlateBlue, 2.0f );
		pRenderAux->DrawLine( point1 + depthOffset, Col_SlateBlue, point2 + depthOffset, Col_SlateBlue, 2.0f );
	}

	const Vec3 firstPoint = worldTM.TransformPoint(volumeInfo.pVertices[0]);
	const Vec3 lastPoint = worldTM.TransformPoint(volumeInfo.pVertices[volumeInfo.verticesCount - 1]);

	pRenderAux->DrawLine( lastPoint, Col_SlateBlue, lastPoint + depthOffset, Col_SlateBlue, 2.0f );
	pRenderAux->DrawLine( lastPoint + depthOffset, Col_SlateBlue, firstPoint + depthOffset, Col_SlateBlue, 2.0f );
}
//--------------------------------------------
void CLaser::GetLaserPositionAndDirection(CWeapon* pParentWeapon, Vec3& pos, Vec3& dir)
{
	const char* entityLocationHelper = m_laserHelperFP.c_str();
	const char* laserTermHelper = "laser_term";
	const bool relative = false;
	const bool absolute = true;

	const int slot = pParentWeapon->IsOwnerFP() ? eIGS_FirstPerson : eIGS_ThirdPerson;

	Matrix34 entityLocation =
		Matrix34::CreateTranslationMat(pParentWeapon->GetSlotHelperPos(slot, entityLocationHelper, absolute)) *
		pParentWeapon->GetSlotHelperRotation(slot, entityLocationHelper, absolute);

	Matrix34 helperLocation =
		Matrix34::CreateTranslationMat(GetSlotHelperPos(slot, laserTermHelper, relative)) *
		GetSlotHelperRotation(slot, laserTermHelper, relative);

	Matrix34 finalLocation = entityLocation * helperLocation;

	pos = finalLocation.GetTranslation();
	dir = finalLocation.GetColumn1();
}
void CMountedGunController::UpdateGunnerLocation( CItem* pMountedGun, IEntity* pParent, const Vec3& bodyDirection )
{
    const SMountParams* pMountParams = pMountedGun->GetMountedParams();

    if (pMountParams)
        {
            f32 bodyDist = pMountParams->body_distance;
            f32 groundDist = pMountParams->ground_distance;

            Matrix34 gunLocalTM  = pMountedGun->GetEntity()->GetLocalTM();

            Matrix34	gunLocalTMXY(IDENTITY);
            Matrix34 characterTM(IDENTITY);
            Matrix34 newGunnerTM;
            Vec3 playerOffset(0.0f, -bodyDist, -groundDist);
            characterTM.SetTranslation(playerOffset);

            IEntity* pControlledPlayerEntity = m_pControlledPlayer->GetEntity();
            IVehicle *pVehicle = NULL;

            if (gEnv->bMultiplayer && m_pControlledPlayer->IsClient() && m_pControlledPlayer->GetLinkedVehicle())
                {
                    newGunnerTM = gunLocalTM;
                    newGunnerTM.SetTranslation(gunLocalTM.GetTranslation() + Quat(gunLocalTM) * playerOffset);
                }
            else
                {
                    float rotZ = pMountedGun->GetEntity()->GetRotation().GetRotZ();
                    gunLocalTMXY.SetRotationZ(rotZ);
                    gunLocalTMXY.SetTranslation(gunLocalTM.GetTranslation());
                    newGunnerTM = gunLocalTMXY*characterTM;
                }

            pControlledPlayerEntity->SetLocalTM(newGunnerTM, ENTITY_XFORM_USER);

//		CryWatch("Mount wrot: plr: %f vehicle: %f wpn: %f", pControlledPlayerEntity->GetWorldRotation().GetRotZ(), pParent ? pParent->GetWorldRotation().GetRotZ() : -99.0f, pMountedGun->GetEntity()->GetWorldRotation().GetRotZ());
//		CryWatch("Mount lrot: plr: %f vehicle: %f wpn: %f", pControlledPlayerEntity->GetRotation().GetRotZ(), pParent ? pParent->GetRotation().GetRotZ() : -99.0f, pMountedGun->GetEntity()->GetRotation().GetRotZ());
        }
}
Example #12
0
//-----------------------------------------------------------------------
void CVehiclePartLight::UpdateLight(const float frameTime)
{ 
  if (m_slot == -1)
    return;

	// move to vehicle event change view?
  if (m_diffuseMult[0] != m_diffuseMult[1])
  {
    SEntitySlotInfo info;
    if (m_pVehicle->GetEntity()->GetSlotInfo(m_slot, info) && info.pLight)
    {
      CDLight& light = info.pLight->GetLightProperties();    

      IActor* pActor = CCryAction::GetCryAction()->GetClientActor();
      bool localPlayer = (pActor != NULL) && (pActor->GetLinkedVehicle() == m_pVehicle);

			IVehicleSeat* pSeat = pActor ? m_pVehicle->GetSeatForPassenger(pActor->GetEntityId()) : NULL;
			IVehicleView* pView = pSeat? pSeat->GetView(pSeat->GetCurrentView()) : NULL;
			bool isThirdPersonView = pView? pView->IsThirdPerson() : true;
      if (localPlayer && !isThirdPersonView)
				light.SetLightColor(ColorF(m_diffuseCol * m_diffuseMult[0], 1.f));
      else
				light.SetLightColor(ColorF(m_diffuseCol * m_diffuseMult[1], 1.f));    
    }
  }  

  if (m_pHelper)
  { 
    const static Matrix33 rot(Matrix33::CreateRotationXYZ(Ang3(0.f, 0.f, DEG2RAD(90.f))));
    
    Matrix34 helperTM;
		m_pHelper->GetVehicleTM(helperTM);
    Matrix34 localTM = Matrix33(helperTM) * rot;
    localTM.SetTranslation(helperTM.GetTranslation());

    GetEntity()->SetSlotLocalTM(m_slot, localTM);  
  }

}
void Matrix34::Test()
{
    Matrix34 a(Vector3(0,0,1), g_upVector, g_zeroVector);
    Matrix34 b(Vector3(0,0,1), g_upVector, g_zeroVector);
    Matrix34 c=a*b;
    DebugOut("c = a * b\n");
    c.WriteToDebugStream();

    Vector3 front(10,20,2);
    front.Normalise();
    Vector3 up(0,1,0);
    Vector3 right = up ^ front;
    right.Normalise();
    up = front ^ right;
    up.Normalise();
    Matrix34 d(front, up, Vector3(-1,2,-3));
    DebugOut("d = \n");
    d.WriteToDebugStream();

    Matrix34 e = d * d;
    DebugOut("e = d * d\n");
    e.WriteToDebugStream();
}
bool CMFXParticleEffect::AttachToEntity( IEntity& targetEntity, const SMFXParticleEntry& particleParams, const SMFXRunTimeEffectParams& params, IParticleEffect* pParticleEffect, const Vec3& dir, float scale )
{
	if (pParticleEffect)
	{
		int effectSlot = targetEntity.LoadParticleEmitter(-1, pParticleEffect);
		if (effectSlot >= 0)
		{
			Matrix34 hitTM;
			hitTM.Set(Vec3(1.0f, 1.0f, 1.0f), Quat::CreateRotationVDir(dir), params.pos);

			Matrix34 localEffectTM = targetEntity.GetWorldTM().GetInverted() * hitTM;
			localEffectTM.ScaleColumn(Vec3(scale, scale, scale));

			CRY_ASSERT(localEffectTM.IsValid());

			targetEntity.SetSlotLocalTM(effectSlot, localEffectTM);

			return true;
		}
	}

	return false;
}
void LogDeformPhysicalEntity( const char * from, IPhysicalEntity * pEnt, const Vec3& p, const Vec3& n, float energy )
{
#if DEBUG_NET_BREAKAGE
	if (!pEnt)
		return;

	if (CNetworkCVars::Get().BreakageLog)
	{
		CryLog("[brk] DeformPhysicalEntity on %s @ (%.8f,%.8f,%.8f); n=(%.8f,%.8f,%.8f); energy=%.8f", from, p.x, p.y, p.z, n.x, n.y, n.z, energy);
		CryLog("[brk]    selector is %s", CObjectSelector::GetDescription(pEnt).c_str());
		switch (pEnt->GetiForeignData())
		{
		case PHYS_FOREIGN_ID_STATIC:
			if (IRenderNode * pRN = (IRenderNode*)pEnt->GetForeignData(PHYS_FOREIGN_ID_STATIC))
			{
				CryLog("[brk]    name is %s", pRN->GetName());
				CryLog("[brk]    entity class name is %s", pRN->GetEntityClassName());
				CryLog("[brk]    debug string is %s", pRN->GetDebugString().c_str());
			}
			break;
		case PHYS_FOREIGN_ID_ENTITY:
			if (IEntity * pEntity = (IEntity*)pEnt->GetForeignData(PHYS_FOREIGN_ID_ENTITY))
			{
				CryLog("[brk]    name is %s", pEntity->GetName());
				Matrix34 m = pEntity->GetWorldTM();
				CryLog("[brk]    world tm:");
				for (int i=0; i<3; i++)
				{
					Vec4 row = m.GetRow4(i);
					CryLog("[brk]       %+12.8f %+12.8f %+12.8f %+12.8f", row[0], row[1], row[2], row[3]);
				}
			}
			break;
		}
	}
#endif
}
Example #16
0
void CBurnEffectManager::CreateBurnEffect(const EventPhysCollision& pCollision, CBurnEffectManager::SBurnPoint* pBurnPoint)
{
	Vec3 surfaceNormal = pCollision.n;
	Vec3 hitDir(ZERO);
	if (pCollision.vloc[0].GetLengthSquared() > 1e-6f)
	{
		hitDir = pCollision.vloc[0].GetNormalized();
	}
	Vec3 surfacePosition = pCollision.pt;
	Vec3 halfVector = (surfaceNormal + (-hitDir)).GetNormalized();

	CItemParticleEffectCache& particleCache = g_pGame->GetGameSharedParametersStorage()->GetItemResourceCache().GetParticleEffectCache();
	IParticleEffect* pParticleEffect = particleCache.GetCachedParticle(pBurnPoint->m_pBurnParams->m_effectName);

	if (pParticleEffect)
	{
		Matrix34 loc;
		loc.SetIdentity();
		loc.SetTranslation(surfacePosition);
		loc.SetRotation33(OrthoNormalVector(surfaceNormal));
		IParticleEmitter* pEffect = pParticleEffect->Spawn(false, loc);
		if(pEffect)
		{
			pEffect->AddRef();
			pBurnPoint->m_effect = pEffect;

			const ParticleParams& particleParams = pParticleEffect->GetParticleParams();

			pBurnPoint->m_attachType = particleParams.eAttachType;
			pBurnPoint->m_attachForm = particleParams.eAttachForm;
		}
		UpdateBurnEffect(pBurnPoint);
	}
	
	UpdateBurnEffect(pBurnPoint);
}
Example #17
0
  SimpleCamera simpleCamera(const Matrix34& P) {

    // P = [A|a] = s K cRw [I|-T], with s the unknown scale
    Matrix3 A = P.topLeftCorner(3, 3);
    Vector3 a = P.col(3);

    // do RQ decomposition to get s*K and cRw angles
    Matrix3 sK;
    Vector3 xyz;
    boost::tie(sK, xyz) = RQ(A);

    // Recover scale factor s and K
    double s = sK(2, 2);
    Matrix3 K = sK / s;

    // Recover cRw itself, and its inverse
    Rot3 cRw = Rot3::RzRyRx(xyz);
    Rot3 wRc = cRw.inverse();

    // Now, recover T from a = - s K cRw T = - A T
    Vector3 T = -(A.inverse() * a);
    return SimpleCamera(Pose3(wRc, T),
        Cal3_S2(K(0, 0), K(1, 1), K(0, 1), K(0, 2), K(1, 2)));
  }
	virtual void ProcessEvent(EFlowEvent event, SActivationInfo *pActInfo)
	{
		
		switch (event)
		{
			case eFE_Initialize:
				{
					pActInfo->pGraph->SetRegularlyUpdated(pActInfo->myID,false);
				}
			case eFE_Activate:
				{
					if(GetPortBool(pActInfo, 1)) {
						EntityId id = GetPortEntityId(pActInfo,EIP_EntityID);
						IEntity * entity = gEnv->pEntitySystem->GetEntity(id);
						if(entity)
						{
							Matrix34 trans; // = entity->GetWorldTM();
							trans.CreateIdentity();
															
							Quat quat =  entity->GetRotation();
							quat.v = GetPortVec3( pActInfo, EIP_Rotation_XYZ);
							quat.w = GetPortFloat( pActInfo, EIP_Rotation_W);
							
							//quat.NormalizeFast();
					
							Vec3 position = entity->GetPos();
							trans.Set(Vec3(1,1,1),quat.GetNormalized(),position);
							
							entity->SetPosRotScale(position,quat,Vec3(1,1,1));

							
						}
					}
				}
			}
	}
Example #19
0
void Robo::getViewMatrix( Matrix34* vm ) const {
	//まず正面方向ベクタを作成
	Vector3 d( 0.0, 0.0, 1.0 );
	Matrix34 m;
	m.setRotationY( mAngleY );
	m.multiply( &d, d );
	//こいつを前方にmCameraTargetDistanceZだけ伸ばす
	Vector3 t;
	t.setMul( d, 20.0 );
	//ロボが高いところにいるならちょっと下を見てやる。これはパラメータにないその場工夫。
	t.y -= mPosition.y * 0.12; //このへんの調整も適当
	//こいつを後方にmCameraDistacneZだけ伸ばす
	Vector3 p;
	p.setMul( d, -20.0 );
	//YにmCameraDistanceYをプラス
	p.y += 20.0;
	//ロボが高いところにいるならちょっと高目にして下を見てやる。これはパラメータにないその場工夫。
	p.y += mPosition.y * 0.12; //このへんの調整も適当
	//ロボ現在位置をプラス
	t += mPosition;
	p += mPosition;
	//ビュー行列作成
	vm->setViewTransform( p, t );
}
Example #20
0
void Model::draw() const {
	Matrix34 wm;
	wm.setTranslation( mPosition );
	wm.rotateY( mAngle.y );
	wm.rotateX( mAngle.x );
	wm.rotateZ( mAngle.z );
	wm.scale( mScale );

	GameLib::Graphics::Manager::instance().setWorldMatrix( wm );
	mBatch->draw();
}
Example #21
0
void Model::draw( const Matrix44& pvm ) const {
	Matrix34 wm;
	wm.setTranslation( mPosition );
	wm.rotateY( mAngle.y );
	wm.rotateX( mAngle.x );
	wm.rotateZ( mAngle.z );
	wm.scale( mScale );

	Matrix44 transform;
	transform.setMul( pvm, wm );

	mBatch->draw( transform );
}
Example #22
0
void Tree::draw(
const Matrix44& pvm,
const Vector3& lightVector,
const Vector3& lightColor,
const Vector3& ambient ) const {
	Matrix34 wm;
	wm.setTranslation( mPosition );
	wm.rotateY( mAngle.y );
	wm.rotateX( mAngle.x );
	wm.rotateZ( mAngle.z );
	wm.scale( mScale );

	//根ノードへ渡す
	if ( mNodes ){
		mNodes[ 0 ].draw(
			pvm,
			wm,
			lightVector,
			lightColor,
			ambient );
	}
}
//------------------------------------------------------------------------
Vec3 CVehicleHelper::GetWorldSpaceTranslation() const
{
	Matrix34 temp;
	GetWorldTM(temp);
	return temp.GetTranslation();
}
//------------------------------------------------------------------------
bool CVehicleViewFirstPerson::Init(IVehicleSeat* pISeat, const CVehicleParams& table)
{
	CVehicleSeat* pSeat = static_cast<CVehicleSeat*>(pISeat);

	if (!CVehicleViewBase::Init(pSeat, table))
		return false;

	if (CVehicleParams paramsTable = table.findChild(m_name))
	{	
		paramsTable.getAttr("offset", m_offset);
		paramsTable.getAttr("hidePlayer", m_hidePlayer);
		paramsTable.getAttr("hideVehicle", m_hideVehicle);
		paramsTable.getAttr("relativeToHorizon", m_relToHorizon);
		paramsTable.getAttr("followSpeed", m_speedRot);
		
		float viewFov;
		if(paramsTable.getAttr("fov", viewFov))
		{
			m_fov = DEG2RAD(viewFov);
		}

		m_sCharacterBoneName = paramsTable.getAttr("characterBone");
		string helperName = paramsTable.getAttr("helper");
	
		if (!helperName.empty())
		{ 
			if (helperName != "auto")
			{ 
				m_pHelper = m_pVehicle->GetHelper(helperName);
			}
			else 
			{
				// create a helper with default viewpos above sithelper    
				const string& seatName = pSeat->GetName();     
				helperName = seatName + string("_ghostview_pos");

				if (IVehicleHelper* pSitHelper = pSeat->GetSitHelper())
				{
					Matrix34 tm;
					pSitHelper->GetVehicleTM(tm);
					Vec3 pos = tm.GetTranslation() + Vec3(0,0,0.625); // player eye height

					m_pVehicle->AddHelper(helperName.c_str(), pos, tm.GetColumn1(), pSitHelper->GetParentPart());
					m_pHelper = m_pVehicle->GetHelper(helperName.c_str());
				}
			}

			if (!m_pHelper)
				GameWarning("[%s, seat %s]: view helper %s not found, using character head", m_pVehicle->GetEntity()->GetName(), m_pSeat->GetName().c_str(), helperName.c_str());
		}    

		string frame = paramsTable.getAttr("frameObject");
		if (!frame.empty())
		{
			// todo: aspect ratio?
			if (strstr(frame, ".cgf"))
				m_frameSlot = m_pVehicle->GetEntity()->LoadGeometry(-1, frame);
			else
				m_frameSlot = m_pVehicle->GetEntity()->LoadCharacter(-1, frame);

			if (m_frameSlot != -1)
			{
				m_pVehicle->GetEntity()->SetSlotFlags(m_frameSlot, m_pVehicle->GetEntity()->GetSlotFlags(m_frameSlot) &~ (ENTITY_SLOT_RENDER|ENTITY_SLOT_RENDER_NEAREST));    

				if (m_pHelper)
				{
					Matrix34 tm;
					m_pHelper->GetVehicleTM(tm);
					m_invFrame = tm.GetInverted();
					m_pVehicle->GetEntity()->SetSlotLocalTM(m_frameSlot, tm);
				}
			}
		}

		paramsTable.getAttr("frameObjectOffset", m_frameObjectOffset);
	}

	if (m_hideVehicle)
		m_hidePlayer = true;

	if (m_speedRot==0.f)
	{
		m_speedRot = 4.0f;

		if (IVehicleMovement* pMovement = m_pVehicle->GetMovement())
		{
			if (pMovement->GetMovementType() == IVehicleMovement::eVMT_Air)
			{
				m_speedRot *= 2.0f;
			}
		}
	}


	Reset();
	return true;
}
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;
}
void CVicinityDependentObjectMover::HandleEvent( const SGameObjectEvent& gameObjectEvent )
{
	const uint32 eventId = gameObjectEvent.event;
	void* pParam = gameObjectEvent.param;
	if ( (eventId == eGFE_ScriptEvent) && (pParam != NULL) )
	{
		const char* szEventName = static_cast<const char*>( pParam );
		if ( strcmp(szEventName, "EnableAreaTrigger") == 0 )
		{
			m_bUseAreaTrigger = true;
		}
		else if ( strcmp(szEventName, "DisableAreaTrigger") == 0 )
		{
			m_bUseAreaTrigger = false;
		}
		else if ( strcmp(szEventName, "MoveTo") == 0 )
		{
			SetState(eObjectRangeMoverState_MovingTo);
		}
		else if ( strcmp(szEventName, "MoveBack") == 0 )
		{
			SetState(eObjectRangeMoverState_MovingBack);
		}
		else if ( strcmp(szEventName, "Reset") == 0 )
		{
			SetState(eObjectRangeMoverState_None);
			ActivateOutputPortBool( "OnReset" );
		}
		else if ( strcmp(szEventName, "ForceToTargetPos") == 0 )
		{
			SetState(eObjectRangeMoverState_MovingTo);
			SetState(eObjectRangeMoverState_Moved);
			ActivateOutputPortBool( "OnForceToTargetPos" );
		}
		else if ( strcmp(szEventName, "ForceToTargetPos") == 0 )
		{
			SetState(eObjectRangeMoverState_MovingTo);
			SetState(eObjectRangeMoverState_Moved);
			ActivateOutputPortBool( "OnForceToTargetPos" );
		}
		else if ( strcmp(szEventName, "ForceReverseMoveToStartPos") == 0 )
		{
			if (!m_bForcedReverseMoveToStartPos)
			{
				m_bForcedReverseMoveToStartPos = true;
				SetState(eObjectRangeMoverState_None);
				IEntity* pEntity = GetEntity();
				CRY_ASSERT(pEntity);

				const Matrix34 worldTransform = pEntity->GetWorldTM();
				const Vec3& vUpNormal = worldTransform.GetColumn2();
				const Vec3 newEntityStartPos = pEntity->GetWorldPos() + (-1.0f*vUpNormal*m_fMoveToDistance); // Set entity pos in opposite direction
				pEntity->SetPos(newEntityStartPos);
			}
		}
		else if ( strcmp(szEventName, "UpdateFromProperties") == 0 )
		{
			Reset(false);
		}

		SetUpdate();
	}
}
Example #27
0
void CBoidObject::CreateArticulatedCharacter(SBoidContext &bc,const Vec3 &size,float mass)
{
	Vec3 orgVelocity = m_speed*m_heading;

	if(m_pPhysics && m_pPhysics->GetType() == PE_PARTICLE)
	{
		pe_params_particle pparams;
		m_pPhysics->GetParams(&pparams);
		orgVelocity = pparams.velocity*pparams.heading;
	}

	if(m_pPhysics)
	{
		m_pPhysics = 0;
	}

	IEntity *pEntity = gEnv->pEntitySystem->GetEntity(m_entity);

	if(!pEntity)
		return;

	Quat q(IDENTITY);
	CalcOrientation(q);

	pe_params_pos bodypos;
	bodypos.pos = m_pos;
	bodypos.q = q;
	bodypos.scale = m_scale;
	bodypos.iSimClass = 2;

	SEntityPhysicalizeParams entityPhysParams;
	entityPhysParams.type = PE_ARTICULATED;
	entityPhysParams.nSlot = 0;
	entityPhysParams.mass = mass;
	entityPhysParams.nLod = 1;
	pEntity->Physicalize(entityPhysParams);

	// After physicalization reset entity slot matrix if present.
	if(!bc.vEntitySlotOffset.IsZero())
	{
		Matrix34 tmIdent;
		tmIdent.SetIdentity();
		pEntity->SetSlotLocalTM(0,tmIdent);
	}

	m_pPhysics =  pEntity->GetPhysics();

	if(!m_pPhysics)
		return;

	m_pPhysics->SetParams(&bodypos);

	//m_pPhysics =  m_object->RelinquishCharacterPhysics();

	pe_params_flags pf;
	pf.flagsOR = pef_never_affect_triggers|pef_never_break;
	m_pPhysics->SetParams(&pf);

	pe_params_articulated_body pab;
	pab.bGrounded = 0;
	pab.bCheckCollisions = 1;
	pab.bCollisionResp = 1;
	m_pPhysics->SetParams(&pab);

	pe_simulation_params symparams;
	symparams.damping = 0.3f;
	symparams.dampingFreefall = 0.2f;
	m_pPhysics->SetParams(&symparams);

	pe_params_buoyancy pb;
	pb.waterDensity = 1000.0f;
	pb.waterDamping = 1;
	pb.waterResistance = 1000;
	pb.waterPlane.n.Set(0,0,1);
	//pb.waterPlane.origin.set(0,0,gEnv->p3DEngine->GetWaterLevel(&m_center));
	pb.waterPlane.origin.Set(0,0,bc.waterLevel);
	m_pPhysics->SetParams(&pb);

	// Set original velocity on ragdoll.
	pe_action_set_velocity psetvel;
	psetvel.v = orgVelocity;
	m_pPhysics->Action(&psetvel);

	pe_params_part pp;
	pp.flagsColliderOR=pp.flagsColliderAND = geom_colltype_debris;
	pp.flagsAND = ~(geom_colltype_vehicle|geom_colltype6);
	m_pPhysics->SetParams(&pp);
}
Example #28
0
	CEventEntityDesc() { matWorldPose.Identity(); }
Example #29
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);
		}
	}
}
void CVicinityDependentObjectMover::SetState( const EObjectRangeMoverState state)
{
	if (m_currentState != state)
	{
		switch (state)
		{
		case eObjectRangeMoverState_None:
			{
				IEntity* pEntity = GetEntity();
				CRY_ASSERT(pEntity);

				/*
				if(IPhysicalEntity *pPhysics = GetEntity()->GetPhysics()) // Stop movement
				{
					pe_action_set_velocity	action_set_velocity;
					action_set_velocity.v = Vec3(0.0f, 0.0f, 0.0f);
					pPhysics->Action(&action_set_velocity);
				}
				*/

				pEntity->SetPos(m_vOriginalPos);
				m_currentState = eObjectRangeMoverState_None;
			}
			break;
		case eObjectRangeMoverState_MovingTo:
			{
				if (m_currentState != eObjectRangeMoverState_Moved)
				{
					if (m_currentState == eObjectRangeMoverState_None)
					{
						// Need to remember original pos before moving
						IEntity* pEntity = GetEntity();
						CRY_ASSERT(pEntity);
						const Vec3 vOriginalPos = pEntity->GetWorldPos();
						m_vOriginalPos = vOriginalPos;

						// Remember target pos
						const Matrix34 worldTransform = pEntity->GetWorldTM();
						const Vec3& vUpNormal = worldTransform.GetColumn2();
						m_vMoveToPos = vOriginalPos + (vUpNormal*m_fMoveToDistance);

						// Move with physics
						/*
						if(IPhysicalEntity *pPhysics = GetEntity()->GetPhysics())
						{
							pe_action_set_velocity	action_set_velocity;
							action_set_velocity.v = vUpNormal * m_fMoveToSpeed;
							pPhysics->Action(&action_set_velocity);
						}
						*/
					}

					m_currentState = eObjectRangeMoverState_MovingTo;

					ActivateOutputPortBool( "MoveToStart" );
				}
			}
			break;
		case eObjectRangeMoverState_MovingBack:
			{
				if (m_currentState != eObjectRangeMoverState_None)
				{
					m_currentState = eObjectRangeMoverState_MovingBack;

					// Move with physics
					/*
					IEntity* pEntity = GetEntity();
					CRY_ASSERT(pEntity);
					const Matrix34 worldTransform = pEntity->GetWorldTM();
					const Vec3& vUpNormal = worldTransform.GetColumn2();
					if(IPhysicalEntity *pPhysics = GetEntity()->GetPhysics())
					{
						pe_action_set_velocity	action_set_velocity;
						action_set_velocity.v = vUpNormal * -1.0f * m_fMoveBackSpeed;
						pPhysics->Action(&action_set_velocity);
					}
					*/
				}

				ActivateOutputPortBool( "MoveBackStart" );
			}
			break;
		case eObjectRangeMoverState_Moved:
			{
				IEntity* pEntity = GetEntity();
				CRY_ASSERT(pEntity);

				/*
				if(IPhysicalEntity *pPhysics = GetEntity()->GetPhysics()) // Stop movement
				{
					pe_action_set_velocity	action_set_velocity;
					action_set_velocity.v = Vec3(0.0f, 0.0f, 0.0f);
					pPhysics->Action(&action_set_velocity);
				}
				*/

				pEntity->SetPos( m_vMoveToPos );
				m_currentState = eObjectRangeMoverState_Moved;

				if (m_bDisableAreaTriggerOnMoveComplete)
				{
					m_bUseAreaTrigger = false;
				}

				ActivateOutputPortBool( "MoveToComplete" );
			}
			break;
		}
	}
}