/*virtual*/ void WBCompEldMesh::Tick(float DeltaTime) { XTRACE_FUNCTION; UpdateMesh(DeltaTime); // Add pseudo root motion. Hack from Couriers. if (m_Mesh && m_Mesh->IsAnimated()) { Vector AnimationVelocity; Angles AnimationRotationalVelocity; GetAnimationVelocity(AnimationVelocity, AnimationRotationalVelocity); if (AnimationVelocity.LengthSquared() > 0.0f || !AnimationRotationalVelocity.IsZero()) { WBCompEldTransform* pTransform = GetEntity()->GetTransformComponent<WBCompEldTransform>(); DEVASSERT(pTransform); // Kill velocity in direction of movement. if (AnimationVelocity.LengthSquared() > 0.0f) { Plane MovementPlane(AnimationVelocity.GetNormalized(), 0.0f); pTransform->SetVelocity( MovementPlane.ProjectVector(pTransform->GetVelocity())); } pTransform->ApplyImpulse(AnimationVelocity); pTransform->ApplyRotationalImpulse(AnimationRotationalVelocity); } } }
void WBCompEldMesh::GetAnimationVelocity(Vector& OutVelocity, Angles& OutRotationalVelocity) { ASSERT(m_Mesh); WBCompEldTransform* pTransform = GetEntity()->GetTransformComponent<WBCompEldTransform>(); DEVASSERT(pTransform); m_Mesh->GetAnimationVelocity(OutVelocity, OutRotationalVelocity); OutVelocity = OutVelocity.RotateBy(pTransform->GetOrientation()); }
void WBCompEldLight::AddLight() { // I don't currently want to support dynamic light-emitting entities. // So this event handles the first time a static entity's location is set. // But if it moves again, that's a problem! if( m_HasAddedLight ) { return; } WBCompEldTransform* pTransform = GetEntity()->GetTransformComponent<WBCompEldTransform>(); DEVASSERT( pTransform ); m_LightLocation = pTransform->GetLocation(); m_HasAddedLight = GetWorld()->AddLightAt( m_LightLocation, m_Radius, m_Color ); }
void WBCompEldMesh::UpdateIrradiance(const float DeltaTime) { ASSERT(m_Mesh); // If needed for optimization, only do this on certain events (loaded, moved, // etc.) WBCompEldTransform* pTransform = GetEntity()->GetTransformComponent<WBCompEldTransform>(); DEVASSERT(pTransform); // Makes no sense to have a mesh and no transform const Vector EntityLocation = pTransform->GetLocation(); EldritchWorld* const pWorld = GetWorld(); const Vector IrradianceOffset = Vector(0.0f, 0.0f, m_IrradianceOffsetZ); SVoxelIrradiance CurrentIrradiance; if (m_UseTwoPointIrradiance) { const Vector LocationA = EntityLocation + IrradianceOffset; const Vector LocationB = LocationA + m_TwoPointIrradianceOffset; CurrentIrradiance = pWorld->BlendIrradiances(LocationA, LocationB); } else { CurrentIrradiance = pWorld->GetIrradianceAt(EntityLocation + IrradianceOffset); } for (auto & DirLight : CurrentIrradiance.m_Light) { DirLight += m_CurrentHighlight; DirLight += m_ConstantIrradiance; } if (m_UseBlendedIrradiance) { const float BlendTime = Saturate(DeltaTime * m_BlendRate); m_BlendedIrradiance = SVoxelIrradiance::Lerp(m_BlendedIrradiance, CurrentIrradiance, BlendTime); m_Mesh->SetIrradianceCube(m_BlendedIrradiance); } else { m_Mesh->SetIrradianceCube(CurrentIrradiance); } }
/*virtual*/ void WBCompEldMesh::DebugRender() const { WBCompEldTransform* pTransform = GetEntity()->GetTransformComponent<WBCompEldTransform>(); DEVASSERT(pTransform); IRenderer* const pRenderer = GetFramework()->GetRenderer(); const Vector EntityLocation = pTransform->GetLocation(); pRenderer->DEBUGDrawCross(EntityLocation + m_Offset, 0.25f, ARGB_TO_COLOR(255, 255, 255, 0)); const Vector IrradianceOffset = Vector(0.0f, 0.0f, m_IrradianceOffsetZ); const Vector IrradianceLocation = EntityLocation + IrradianceOffset; pRenderer->DEBUGDrawCross(IrradianceLocation, 0.25f, ARGB_TO_COLOR(255, 0, 255, 255)); if (m_UseTwoPointIrradiance) { pRenderer->DEBUGDrawCross(IrradianceLocation + m_TwoPointIrradianceOffset, 0.25f, ARGB_TO_COLOR(255, 0, 255, 255)); } pRenderer->DEBUGDrawBox(m_Mesh->m_AABB.m_Min, m_Mesh->m_AABB.m_Max, ARGB_TO_COLOR(255, 255, 0, 255)); }
bool WBCompEldMesh::UpdateMeshTransform() { ASSERT(m_Mesh); WBCompEldTransform* pTransform = GetEntity()->GetTransformComponent<WBCompEldTransform>(); DEVASSERT(pTransform); // Makes no sense to have a mesh and no transform const Vector EntityLocation = pTransform->GetLocation(); const Vector CurrentLocation = EntityLocation + m_Offset; m_Mesh->m_Location = CurrentLocation; const Angles EntityOrientation = pTransform->GetOrientation(); m_Mesh->m_Rotation = EntityOrientation; // Optimization, avoid the matrix and AABB calcs if nothing has changed if (m_OldTransform_Location != m_Mesh->m_Location || m_OldTransform_Rotation != m_Mesh->m_Rotation || m_OldTransform_Scale != m_Mesh->m_Scale || m_ForceUpdateTransform) { m_OldTransform_Location = m_Mesh->m_Location; m_OldTransform_Rotation = m_Mesh->m_Rotation; m_OldTransform_Scale = m_Mesh->m_Scale; m_ForceUpdateTransform = false; // Seems like maybe this AABB stuff should be done routinely in the Mesh. :/ const Matrix ScaleMatrix = Matrix::CreateScale(m_Mesh->m_Scale); const Matrix RotationMatrix = EntityOrientation.ToMatrix(); const Matrix TranslationMatrix = Matrix::CreateTranslation(CurrentLocation); const Matrix AABBTransform = ScaleMatrix * RotationMatrix * TranslationMatrix; m_Mesh->m_AABB = m_MeshOriginalAABB.GetTransformedBound(AABBTransform); return true; } else { return false; } }