📄 debriscloud.cpp
字号:
#include "gosFXHeaders.hpp"
//==========================================================================//
// File: gosFX_DebrisCloud.cpp //
// Contents: Base gosFX::DebrisCloud Component //
//---------------------------------------------------------------------------//
// Copyright (C) Microsoft Corporation. All rights reserved. //
//===========================================================================//
//
//############################################################################
//######################## gosFX::DebrisCloud__Specification #############################
//############################################################################
//------------------------------------------------------------------------------
//
gosFX::DebrisCloud__Specification::DebrisCloud__Specification(
Stuff::MemoryStream *stream,
int gfx_version
):
Effect__Specification(gosFX::DebrisCloudClassID, stream, gfx_version)
{
Check_Pointer(this);
Verify(m_class == DebrisCloudClassID);
Verify(gos_GetCurrentHeap() == Heap);
m_minimumDeviation.Load(stream, gfx_version); // ConstantCurve
m_maximumDeviation.Load(stream, gfx_version); // SplineCurve
m_startingSpeed.Load(stream, gfx_version); // SeededCurveOf<ComplexCurve, ComplexCurve,Curve::e_ComplexComplexType>
m_pLifeSpan.Load(stream, gfx_version); // SeededCurveOf<ComplexCurve, SplineCurve,Curve::e_ComplexSplineType>
m_pEtherVelocityY.Load(stream, gfx_version); // SeededCurveOf<ConstantCurve, LinearCurve,Curve::e_ConstantLinearType>
m_pAccelerationY.Load(stream, gfx_version); // SeededCurveOf<SplineCurve, LinearCurve,Curve::e_SplineLinearType>
m_pDrag.Load(stream, gfx_version); // SeededCurveOf<ComplexCurve, ComplexCurve,Curve::e_ComplexComplexType>
m_pAlpha.Load(stream, gfx_version); // SeededCurveOf<ComplexCurve, LinearCurve,Curve::e_ComplexLinearType>
m_pSpin.Load(stream, gfx_version); // SeededCurveOf<ConstantCurve, LinearCurve,Curve::e_ConstantLinearType>
*stream >> centerOfForce; // Stuff::Point3D
LoadGeometry(stream);
}
//------------------------------------------------------------------------------
//
gosFX::DebrisCloud__Specification::DebrisCloud__Specification():
Effect__Specification(gosFX::DebrisCloudClassID)
{
Check_Pointer(this);
Verify(gos_GetCurrentHeap() == Heap);
debrisPieces.SetLength(0);
debrisPositions.SetLength(0);
debrisSpheres.SetLength(0);
debrisSeed.SetLength(0);
}
//------------------------------------------------------------------------------
//
gosFX::DebrisCloud__Specification::~DebrisCloud__Specification()
{
Check_Object(this);
int i, nrOfParticles = debrisPieces.GetLength();
for(i=0;i<nrOfParticles;i++)
{
Check_Object(debrisPieces[i]);
debrisPieces[i]->DetachReference();
}
debrisPieces.SetLength(0);
debrisPositions.SetLength(0);
debrisSpheres.SetLength(0);
debrisSeed.SetLength(0);
}
//------------------------------------------------------------------------------
//
gosFX::DebrisCloud__Specification*
gosFX::DebrisCloud__Specification::Make(
Stuff::MemoryStream *stream,
int gfx_version
)
{
Check_Object(stream);
gos_PushCurrentHeap(Heap);
DebrisCloud__Specification *spec =
new gosFX::DebrisCloud__Specification(stream, gfx_version);
gos_PopCurrentHeap();
return spec;
}
//------------------------------------------------------------------------------
//
void
gosFX::DebrisCloud__Specification::Save(Stuff::MemoryStream *stream)
{
Check_Object(this);
Check_Object(stream);
Effect__Specification::Save(stream);
m_minimumDeviation.Save(stream); // ConstantCurve
m_maximumDeviation.Save(stream); // SplineCurve
m_startingSpeed.Save(stream); // SeededCurveOf<ComplexCurve, ComplexCurve,Curve::e_ComplexComplexType>
m_pLifeSpan.Save(stream); // SeededCurveOf<ComplexCurve, SplineCurve,Curve::e_ComplexSplineType>
m_pEtherVelocityY.Save(stream); // SeededCurveOf<ConstantCurve, LinearCurve,Curve::e_ConstantLinearType>
m_pAccelerationY.Save(stream); // SeededCurveOf<SplineCurve, LinearCurve,Curve::e_SplineLinearType>
m_pDrag.Save(stream); // SeededCurveOf<ComplexCurve, ComplexCurve,Curve::e_ComplexComplexType>
m_pAlpha.Save(stream); // SeededCurveOf<ComplexCurve, LinearCurve,Curve::e_ComplexLinearType>
m_pSpin.Save(stream); // SeededCurveOf<ConstantCurve, LinearCurve,Curve::e_ConstantLinearType>
*stream << centerOfForce; // Stuff::Point3D
MidLevelRenderer::WriteMLRVersion(stream);
int i, nrOfParticles = debrisPieces.GetLength();
*stream << nrOfParticles;
for(i=0;i<nrOfParticles;i++)
{
*stream << debrisPositions[i];
*stream << debrisSpheres[i].center;
*stream << debrisSpheres[i].radius;
Check_Object(debrisPieces[i]);
debrisPieces[i]->Save(stream);
}
}
//------------------------------------------------------------------------------
//
void
gosFX::DebrisCloud__Specification::Copy(DebrisCloud__Specification *spec)
{
Check_Object(this);
Check_Object(spec);
Effect__Specification::Copy(spec);
gos_PushCurrentHeap(Heap);
m_minimumDeviation = spec->m_minimumDeviation; // ConstantCurve
m_maximumDeviation = spec->m_maximumDeviation; // SplineCurve
m_startingSpeed = spec->m_startingSpeed; // SeededCurveOf<ComplexCurve, ComplexCurve,Curve::e_ComplexComplexType>
m_pLifeSpan = spec->m_pLifeSpan; // SeededCurveOf<ComplexCurve, SplineCurve,Curve::e_ComplexSplineType>
m_pEtherVelocityY = spec->m_pEtherVelocityY; // SeededCurveOf<ConstantCurve, LinearCurve,Curve::e_ConstantLinearType>
m_pAccelerationY = spec->m_pAccelerationY; // SeededCurveOf<SplineCurve, LinearCurve,Curve::e_SplineLinearType>
m_pDrag = spec->m_pDrag; // SeededCurveOf<ComplexCurve, ComplexCurve,Curve::e_ComplexComplexType>
m_pAlpha = spec->m_pAlpha; // SeededCurveOf<ComplexCurve, LinearCurve,Curve::e_ComplexLinearType>
m_pSpin = spec->m_pSpin; // SeededCurveOf<ConstantCurve, LinearCurve,Curve::e_ConstantLinearType>
centerOfForce = spec->centerOfForce; // Stuff::Point3D
int i, nrOfParticles = spec->debrisPieces.GetLength();
debrisPieces.SetLength(nrOfParticles);
debrisPositions.SetLength(nrOfParticles);
debrisSpheres.SetLength(nrOfParticles);
debrisSeed.SetLength(nrOfParticles);
for(i=0;i<nrOfParticles;i++)
{
debrisPositions[i] = spec->debrisPositions[i];
debrisSpheres[i] = spec->debrisSpheres[i];
debrisPieces[i] = spec->debrisPieces[i];
Check_Object(debrisPieces[i]);
debrisPieces[i]->AttachReference();
debrisSeed[i] = spec->debrisSeed[i];
}
gos_PopCurrentHeap();
}
//------------------------------------------------------------------------------
//
void
gosFX::DebrisCloud__Specification::LoadGeometry(Stuff::MemoryStream *stream)
{
int i, mlrVersion, nrOfParticles;
mlrVersion = MidLevelRenderer::ReadMLRVersion(stream);
*stream >> nrOfParticles;
debrisPieces.SetLength(nrOfParticles);
debrisPositions.SetLength(nrOfParticles);
debrisSpheres.SetLength(nrOfParticles);
debrisSeed.SetLength(nrOfParticles);
Stuff::Scalar minRadius = 100000000000.0f, maxRadius = 0.0f;
for(i=0;i<nrOfParticles;i++)
{
*stream >> debrisPositions[i];
*stream >> debrisSpheres[i].center;
*stream >> debrisSpheres[i].radius;
if(debrisSpheres[i].radius < minRadius)
{
minRadius = debrisSpheres[i].radius;
}
if(debrisSpheres[i].radius > maxRadius)
{
maxRadius = debrisSpheres[i].radius;
}
//
//---------------
// Load the shape
//---------------
//
debrisPieces[i] =
MidLevelRenderer::MLRShape::Make(
stream,
mlrVersion
);
Register_Object(debrisPieces[i]);
}
Verify(maxRadius > minRadius);
for(i=0;i<nrOfParticles;i++)
{
debrisSeed[i] = (debrisSpheres[i].radius-minRadius)/(maxRadius-minRadius);
}
}
//------------------------------------------------------------------------------
//
void
gosFX::DebrisCloud__Specification::BuildDefaults()
{
Check_Object(this);
Effect__Specification::BuildDefaults();
centerOfForce = Stuff::Point3D(0.0f, 00.0f, 0.0f);
m_lifeSpan.SetCurve(20.0f);
m_minimumDeviation.SetCurve(0.0f);
m_maximumDeviation.SetCurve(Stuff::Pi_Over_6);
m_startingSpeed.m_ageCurve.SetCurve(1.0f);
m_startingSpeed.m_seeded = true;
m_startingSpeed.m_seedCurve.SetCurve(1.0f, 3.0f);
m_pEtherVelocityY.m_ageCurve.SetCurve(0.0f);
m_pEtherVelocityY.m_seeded = false;
m_pEtherVelocityY.m_seedCurve.SetCurve(1.0f);
m_pAccelerationY.m_ageCurve.SetCurve(-9.8f);
m_pAccelerationY.m_seeded = false;
m_pAccelerationY.m_seedCurve.SetCurve(1.0f);
m_pDrag.m_ageCurve.SetCurve(0.3f);
m_pDrag.m_seeded = false;
m_pDrag.m_seedCurve.SetCurve(1.0f);
m_pAlpha.m_ageCurve.SetCurve(1.0f);
m_pAlpha.m_seeded = false;
m_pAlpha.m_seedCurve.SetCurve(1.0f);
m_pSpin.m_ageCurve.SetCurve(Stuff::Pi_Over_2);
m_pSpin.m_seeded = true;
m_pSpin.m_seedCurve.SetCurve(-1.0f, 1.0f);
m_pLifeSpan.m_ageCurve.SetCurve(20.0f);
m_pLifeSpan.m_seeded = false;
m_pLifeSpan.m_seedCurve.SetCurve(1.0f);
}
//------------------------------------------------------------------------------
//
bool
gosFX::DebrisCloud__Specification::IsDataValid(bool fix_data)
{
Check_Object(this);
return Effect__Specification::IsDataValid(fix_data);
/*
centerOfForce = Stuff::Point3D(0.0f, 00.0f, 0.0f);
m_lifeSpan.SetCurve(20.0f);
m_minimumDeviation.SetCurve(0.0f);
m_maximumDeviation.SetCurve(Stuff::Pi_Over_6);
m_startingSpeed.m_ageCurve.SetCurve(1.0f);
m_startingSpeed.m_seeded = true;
m_startingSpeed.m_seedCurve.SetCurve(1.0f, 3.0f);
m_pEtherVelocityY.m_ageCurve.SetCurve(0.0f);
m_pEtherVelocityY.m_seeded = false;
m_pEtherVelocityY.m_seedCurve.SetCurve(1.0f);
m_pAccelerationY.m_ageCurve.SetCurve(-9.8f);
m_pAccelerationY.m_seeded = false;
m_pAccelerationY.m_seedCurve.SetCurve(1.0f);
m_pDrag.m_ageCurve.SetCurve(0.3f);
m_pDrag.m_seeded = false;
m_pDrag.m_seedCurve.SetCurve(1.0f);
m_pAlpha.m_ageCurve.SetCurve(1.0f);
m_pAlpha.m_seeded = false;
m_pAlpha.m_seedCurve.SetCurve(1.0f);
m_pSpin.m_ageCurve.SetCurve(Stuff::Pi_Over_2);
m_pSpin.m_seeded = true;
m_pSpin.m_seedCurve.SetCurve(-1.0f, 1.0f);
m_pLifeSpan.m_ageCurve.SetCurve(20.0f);
m_pLifeSpan.m_seeded = false;
m_pLifeSpan.m_seedCurve.SetCurve(1.0f);
*/
}
//############################################################################
//########################## gosFX::DebrisCloud ############################
//############################################################################
gosFX::DebrisCloud::ClassData*
gosFX::DebrisCloud::DefaultData = NULL;
//------------------------------------------------------------------------------
//
void
gosFX::DebrisCloud::InitializeClass()
{
Verify(!DefaultData);
Verify(gos_GetCurrentHeap() == Heap);
DefaultData =
new ClassData(
DebrisCloudClassID,
"gosFX::DebrisCloud",
EffectCloud::DefaultData,
(Effect::Factory)&Make,
(Specification::Factory)&Specification::Make
);
Register_Object(DefaultData);
}
//------------------------------------------------------------------------------
//
void
gosFX::DebrisCloud::TerminateClass()
{
Unregister_Object(DefaultData);
delete DefaultData;
DefaultData = NULL;
}
//------------------------------------------------------------------------------
//
gosFX::DebrisCloud::DebrisCloud(
Specification *spec,
unsigned flags
):
Effect(DefaultData, spec, flags)
{
Verify(gos_GetCurrentHeap() == Heap);
debrisPieces.SetLength(spec->debrisPieces.GetLength());
}
//------------------------------------------------------------------------------
//
gosFX::DebrisCloud*
gosFX::DebrisCloud::Make(
Specification *spec,
unsigned flags
)
{
Check_Object(spec);
gos_PushCurrentHeap(Heap);
DebrisCloud *cloud = new gosFX::DebrisCloud(spec, flags);
gos_PopCurrentHeap();
return cloud;
}
//------------------------------------------------------------------------------
//
void
gosFX::DebrisCloud::Start(struct gosFX::Effect::ExecuteInfo *info)
{
Check_Object(this);
Check_Pointer(info);
//
//--------------------------------------------------------------------------
// Let effect initialize, then figure out how many particles we want to make
//--------------------------------------------------------------------------
//
Effect::Start(info);
Specification *spec = GetSpecification();
Check_Object(spec);
Verify(debrisPieces.GetLength() == spec->debrisPieces.GetLength());
int i, numOfParticles = debrisPieces.GetLength();
for(i=0;i<numOfParticles;i++)
{
Particle *particle = &debrisPieces[i];
particle->m_localToParent = Stuff::LinearMatrix4D::Identity;
particle->m_localToParent.BuildTranslation(spec->debrisPositions[i]);
particle->m_age = 0.0f;
particle->m_seed = spec->debrisSeed[i];
Stuff::Scalar lifetime =
spec->m_pLifeSpan.ComputeValue(0.0f, particle->m_seed);
Min_Clamp(lifetime, 0.0333333f);
particle->m_ageRate = 1.0f / lifetime;
Stuff::Vector3D v;
v.Subtract(spec->debrisPositions[i], spec->centerOfForce);
// v.y = 0.0f;
Stuff::Scalar lerpFactor =
Stuff::Lerp(
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -