📄 spinningcloud.cpp
字号:
- particle->m_radius*particle->m_scale;
local_box.maxZ =
particle->m_localTranslation.z
+ particle->m_radius*particle->m_scale;
box.Union(box, local_box);
}
}
//
//------------------------------------
// Now, build a info->m_bounds around this box
//------------------------------------
//
Verify(box.maxX >= box.minX);
Verify(box.maxY >= box.minY);
Verify(box.maxZ >= box.minZ);
Stuff::OBB local_bounds = Stuff::OBB::Identity;
local_bounds.axisExtents.x = 0.5f * (box.maxX - box.minX);
local_bounds.axisExtents.y = 0.5f * (box.maxY - box.minY);
local_bounds.axisExtents.z = 0.5f * (box.maxZ - box.minZ);
local_bounds.localToParent(3,0) = box.minX + local_bounds.axisExtents.x;
local_bounds.localToParent(3,1) = box.minY + local_bounds.axisExtents.y;
local_bounds.localToParent(3,2) = box.minZ + local_bounds.axisExtents.z;
local_bounds.sphereRadius = local_bounds.axisExtents.GetLength();
if (local_bounds.sphereRadius < Stuff::SMALL)
local_bounds.sphereRadius = 0.01f;
Stuff::OBB parent_bounds;
parent_bounds.Multiply(local_bounds, m_localToParent);
info->m_bounds->Union(*info->m_bounds, parent_bounds);
}
//
//----------------------------------------------
// Tell our caller that we get to keep executing
//----------------------------------------------
//
return true;
}
//------------------------------------------------------------------------------
//
void
gosFX::SpinningCloud::CreateNewParticle(
unsigned index,
Stuff::Point3D *translation
)
{
//
//---------------------------
// Let our parent do creation
//---------------------------
//
ParticleCloud::CreateNewParticle(index, translation);
//
//--------------------------------------
// Figure out where the particle is born
//--------------------------------------
//
Specification *spec = GetSpecification();
Check_Object(spec);
Particle *particle = GetParticle(index);
Check_Object(particle);
Stuff::Scalar seed = particle->m_seed;
Stuff::Scalar age = m_age;
particle->m_localTranslation = *translation;
//
//---------------------------------
// Figure out the particle rotation
//---------------------------------
//
particle->m_angularVelocity.x = spec->m_pSpin.ComputeValue(age, seed);
particle->m_angularVelocity.y = spec->m_pSpin.ComputeValue(age, seed);
particle->m_angularVelocity.z = spec->m_pSpin.ComputeValue(age, seed);
//
//-----------------------------------------------------
// If we are aligning with velocity, deal with that now
//-----------------------------------------------------
//
if (spec->m_alignYUsingVelocity)
{
Stuff::LinearMatrix4D basis(true);
basis.AlignLocalAxisToWorldVector(
particle->m_localLinearVelocity,
Stuff::Y_Axis,
Stuff::X_Axis,
Stuff::Z_Axis
);
particle->m_localRotation = basis;
}
else if (spec->m_randomStartingRotation)
{
Stuff::EulerAngles
rotation(
Stuff::Two_Pi*Stuff::Random::GetFraction(),
Stuff::Pi*Stuff::Random::GetFraction(),
Stuff::Two_Pi*Stuff::Random::GetFraction()
);
particle->m_localRotation = rotation;
}
else
particle->m_localRotation = Stuff::UnitQuaternion::Identity;
}
//------------------------------------------------------------------------------
//
bool
gosFX::SpinningCloud::AnimateParticle(
unsigned index,
const Stuff::LinearMatrix4D *world_to_new_local,
Stuff::Time till
)
{
Check_Object(this);
//
//-----------------------------------------------------------------------
// If this cloud is unparented, we need to transform the point from local
// space into world space and set the internal position/velocity pointers
// to these temporary values
//-----------------------------------------------------------------------
//
Particle *particle = GetParticle(index);
Check_Object(particle);
Stuff::Scalar age = particle->m_age;
if (age >= 1.0f)
return false;
Stuff::Point3D *translation = &particle->m_localTranslation;
Stuff::UnitQuaternion *rotation = &particle->m_localRotation;
Stuff::Vector3D *velocity = &particle->m_localLinearVelocity;
int sim_mode = GetSimulationMode();
if (sim_mode == DynamicWorldSpaceSimulationMode)
{
particle->m_worldTranslation.Multiply(*translation, m_localToWorld);
Stuff::LinearMatrix4D local_rot(*rotation);
Stuff::LinearMatrix4D world_rot;
world_rot.Multiply(local_rot, m_localToWorld);
particle->m_worldRotation = world_rot;
particle->m_worldLinearVelocity.Multiply(*velocity, m_localToWorld);
translation = &particle->m_worldTranslation;
rotation = &particle->m_worldRotation;
velocity = &particle->m_worldLinearVelocity;
}
Check_Object(translation);
Check_Object(rotation);
Check_Object(velocity);
//
//------------------------------------------------------------------
// First, calculate the drag on the particle. Drag can never assist
// velocity
//------------------------------------------------------------------
//
Stuff::Scalar seed = particle->m_seed;
Specification *spec = GetSpecification();
Check_Object(spec);
Stuff::Scalar drag = -spec->m_pDrag.ComputeValue(age, seed);
Max_Clamp(drag, 0.0f);
Stuff::Vector3D ether;
ether.x = spec->m_pEtherVelocityX.ComputeValue(age, seed);
ether.y = spec->m_pEtherVelocityY.ComputeValue(age, seed);
ether.z = spec->m_pEtherVelocityZ.ComputeValue(age, seed);
Stuff::Vector3D accel(Stuff::Vector3D::Identity);
//
//-------------------------------------------------------------------
// Deal with pseudo-world simulation. In this mode, we interpret the
// forces as if they are already in worldspace, and we transform them
// back to local space
//-------------------------------------------------------------------
//
if (sim_mode == StaticWorldSpaceSimulationMode)
{
Stuff::LinearMatrix4D world_to_effect;
world_to_effect.Invert(m_localToWorld);
Stuff::Vector3D local_ether;
local_ether.MultiplyByInverse(ether, world_to_effect);
Stuff::Vector3D rel_vel;
rel_vel.Subtract(*velocity, local_ether);
accel.Multiply(rel_vel, drag);
//
//-----------------------------------------
// Now, add in acceleration of the particle
//-----------------------------------------
//
Stuff::Vector3D world_accel;
world_accel.x = spec->m_pAccelerationX.ComputeValue(age, seed);
world_accel.y = spec->m_pAccelerationY.ComputeValue(age, seed);
world_accel.z = spec->m_pAccelerationZ.ComputeValue(age, seed);
Stuff::Vector3D local_accel;
local_accel.Multiply(world_accel, world_to_effect);
accel += local_accel;
}
//
//----------------------------------------------------------------------
// Otherwise, just add the forces in the same space the particles are in
//----------------------------------------------------------------------
//
else
{
Stuff::Vector3D rel_vel;
rel_vel.Subtract(*velocity, ether);
accel.Multiply(rel_vel, drag);
//
//-----------------------------------------
// Now, add in acceleration of the particle
//-----------------------------------------
//
accel.x += spec->m_pAccelerationX.ComputeValue(age, seed);
accel.y += spec->m_pAccelerationY.ComputeValue(age, seed);
accel.z += spec->m_pAccelerationZ.ComputeValue(age, seed);
}
//
//-------------------------------------------------
// Compute the particle's new velocity and position
//-------------------------------------------------
//
Stuff::Scalar time_slice =
static_cast<Stuff::Scalar>(till - m_lastRan);
velocity->AddScaled(*velocity, accel, time_slice);
translation->AddScaled(*translation, *velocity, time_slice);
//
//-----------------------
// Deal with the rotation
//-----------------------
//
if (!spec->m_alignYUsingVelocity)
{
Stuff::Vector3D omega(particle->m_angularVelocity);
omega *= time_slice;
Stuff::UnitQuaternion omega_q;
omega_q = omega;
rotation->Multiply(omega_q, Stuff::UnitQuaternion(*rotation));
rotation->Normalize();
}
//
//---------------------------------------------------------------------
// If we are unparented, we need to transform the velocity and position
// data back into the NEW local space
//---------------------------------------------------------------------
//
if (sim_mode == DynamicWorldSpaceSimulationMode)
{
Check_Object(world_to_new_local);
particle->m_localLinearVelocity.Multiply(*velocity, *world_to_new_local);
particle->m_localTranslation.Multiply(*translation, *world_to_new_local);
Stuff::LinearMatrix4D world_rot(*rotation);
Stuff::LinearMatrix4D local_rot;
local_rot.Multiply(world_rot, *world_to_new_local);
particle->m_localRotation = local_rot;
}
//
//------------------------------------------------------------
// If we are aligning Y using velocity, do the calculation now
//------------------------------------------------------------
//
if (spec->m_alignYUsingVelocity)
{
Stuff::LinearMatrix4D basis(true);
basis.AlignLocalAxisToWorldVector(
particle->m_localLinearVelocity,
Stuff::Y_Axis,
Stuff::X_Axis,
Stuff::Z_Axis
);
particle->m_localRotation = basis;
}
//
//------------------
// Animate the scale
//------------------
//
particle->m_scale = spec->m_pScale.ComputeValue(age, seed);
return true;
}
//------------------------------------------------------------------------------
//
void
gosFX::SpinningCloud::TestInstance() const
{
Verify(IsDerivedFrom(DefaultData));
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -