ad5cd7b16a
match the genesis editor version 1.3.1.921.
892 lines
27 KiB
C++
892 lines
27 KiB
C++
/****************************************************************************
|
||
Copyright (c) 2011-2013,WebJet Business Division,CYOU
|
||
|
||
http://www.genesis-3d.com.cn
|
||
|
||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||
of this software and associated documentation files (the "Software"), to deal
|
||
in the Software without restriction, including without limitation the rights
|
||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||
copies of the Software, and to permit persons to whom the Software is
|
||
furnished to do so, subject to the following conditions:
|
||
|
||
The above copyright notice and this permission notice shall be included in
|
||
all copies or substantial portions of the Software.
|
||
|
||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||
THE SOFTWARE.
|
||
****************************************************************************/
|
||
#include "stdneb.h"
|
||
#include "appframework/actor.h"
|
||
#include "particlefeature/components/particlerenderobject.h"
|
||
#include "particlefeature/components/particlerendercomponent.h"
|
||
#include "particlefeature/particlefeatureprotocol.h"
|
||
#include "graphicfeature/graphicsfeatureprotocol.h"
|
||
#include "particles/particletarget.h"
|
||
#include "particles/targets/particleEntityTarget.h"
|
||
#include "particles/particleserver.h"
|
||
#include "serialization/serializeserver.h"
|
||
#include "graphicfeature/graphicsfeature.h"
|
||
#include "basegamefeature/managers/timemanager.h"
|
||
#include "basegamefeature/managers/timesource.h"
|
||
#include "graphicfeature/components/skinnedmeshrendercomponent.h"
|
||
|
||
#include "particles/affectors/particleLinearForceAffector.h"
|
||
#include "particles/affectors/particleTextureRotatorAffector.h"
|
||
#include "particles/affectors/particleGravityAffector.h"
|
||
#include "particles/affectors/particleVortexAffector.h"
|
||
#include "particles/affectors/particleLimitAffector.h"
|
||
#include "particles/affectors/particleColorAffector.h"
|
||
#include "particles/affectors/particleMovementAffector.h"
|
||
#include "particles/affectors/particleScaleAffector.h"
|
||
#include "particles/affectors/particleTextureAnimatorAffector.h"
|
||
|
||
#include "particles/emitters/particleSphereSurfaceEmitter.h"
|
||
#include "particles/emitters/particleModelEmitter.h"
|
||
#include "particles/emitters/particleBoxEmitter.h"
|
||
#include "particles/emitters/particleConeEmitter.h"
|
||
#include "particles/targets/particlebillboardtarget.h"
|
||
#include "particles/targets/particleDecalTarget.h"
|
||
#include "particles/targets/particleGPUTarget.h"
|
||
#include "particles/targets/particleEntityTarget.h"
|
||
|
||
#include "graphicfeature/components/skinnedmeshrendercomponent.h"
|
||
|
||
namespace App
|
||
{
|
||
using namespace Resources;
|
||
using namespace Particles;
|
||
using namespace RenderBase;
|
||
using namespace Graphic;
|
||
|
||
__ImplementClass(App::ParticleRenderComponent, 'APRC', App::RenderComponent);
|
||
|
||
//------------------------------------------------------------------------
|
||
ParticleRenderComponent::ParticleRenderComponent()
|
||
: mIsBuild(false)
|
||
, mIsAttached(false)
|
||
, mIsTrans(false)
|
||
, mPrimitiveResInfo(NULL)
|
||
, mEmitMeshRes(NULL)
|
||
, mShowSimpleShape(false)
|
||
, mSelectTech(0)
|
||
, mTemplateName("sys:Mesh.template")
|
||
, mCurCamera(NULL)
|
||
{
|
||
mMeshInfo.dirty = false;
|
||
mMeshInfo.meshID = "sys:box.mesh";
|
||
mMeshInfo.priority = Resources::ResourcePriority::Synchronization;
|
||
}
|
||
//------------------------------------------------------------------------
|
||
void ParticleRenderComponent::InitParticleSystem()
|
||
{
|
||
GPtr<ParticleSystem> ParSystem = ParticleSystem::Create();
|
||
{
|
||
GPtr<SphereSurfaceEmitter> emitter = SphereSurfaceEmitter::Create();
|
||
emitter->getMinMaxCurve(Emitter_SphereRadius)->SetScalar(0.1f);
|
||
ParSystem->SetEmitter( emitter.get() );
|
||
|
||
GPtr<ParticleAffector> pAffector = ParticleAffector::Create();
|
||
ParSystem->AddAffector( pAffector.get() );
|
||
|
||
GPtr<ParticleBillBoardTarget> target = ParticleBillBoardTarget::Create();
|
||
ParSystem->SetTarget( target.get() );
|
||
}
|
||
ParSystem->SetName(Util::String("system_14"));
|
||
this->SetParticleSystem(ParSystem);
|
||
|
||
//create Matrails
|
||
this->SetMaterialID(0, "sys:Default_Particle.material");
|
||
}
|
||
//------------------------------------------------------------------------
|
||
void ParticleRenderComponent::InitMobielParticle()
|
||
{
|
||
GPtr<ParticleSystem> ParSystem = ParticleSystem::Create();
|
||
{
|
||
GPtr<SphereSurfaceEmitter> emitter = SphereSurfaceEmitter::Create();
|
||
emitter->getMinMaxCurve(Emitter_SphereRadius)->SetScalar(0.1f);
|
||
ParSystem->SetEmitter( emitter.get() );
|
||
|
||
GPtr<ParticleGPUTarget> target = ParticleGPUTarget::Create();
|
||
ParSystem->SetTarget( target.get() );
|
||
}
|
||
ParSystem->SetName(Util::String("system_14"));
|
||
this->SetParticleSystem(ParSystem);
|
||
|
||
//create Matrails
|
||
this->SetMaterialID(0, "sys:Default_MobielParticle.material");
|
||
}
|
||
//------------------------------------------------------------------------
|
||
ParticleRenderComponent::~ParticleRenderComponent()
|
||
{
|
||
mPrimitiveResInfo = NULL;
|
||
}
|
||
//------------------------------------------------------------------------
|
||
void
|
||
ParticleRenderComponent::SetupCallbacks(void)
|
||
{
|
||
mActor->RegisterComponentCallback(this, BeginFrame );
|
||
mActor->RegisterComponentCallback(this, OnFrame );
|
||
mActor->RegisterComponentCallback(this, MoveAfter);
|
||
Super::SetupCallbacks();
|
||
}
|
||
//------------------------------------------------------------------------
|
||
void
|
||
ParticleRenderComponent::SetupAcceptedMessages()
|
||
{
|
||
Super::SetupAcceptedMessages();
|
||
}
|
||
//------------------------------------------------------------------------
|
||
void
|
||
ParticleRenderComponent::HandleMessage(const GPtr<Messaging::Message>& msg)
|
||
{
|
||
}
|
||
|
||
//------------------------------------------------------------------------
|
||
void ParticleRenderComponent::SetRenderShapeEnable(bool enable)
|
||
{
|
||
|
||
//[zhongdaohuan][render_obj
|
||
|
||
}
|
||
//------------------------------------------------------------------------
|
||
void ParticleRenderComponent::OnActivate()
|
||
{
|
||
if ( mParticleSystem.isvalid() )
|
||
{
|
||
mParticleSystem->Active();
|
||
|
||
if ( NULL!=mActor )
|
||
{
|
||
mParticleSystem->SetWorldMatrix( mActor->GetWorldTransform() );
|
||
}
|
||
}
|
||
|
||
n_assert( mRenderDates.Size() == 0 );
|
||
|
||
LoadEmitterMesh();
|
||
BuildRenderData();
|
||
|
||
Graphic::GraphicSystem::Instance()->m_BeforeDrawEvent += Delegates::newDelegate(this, &ParticleRenderComponent::_updateTarget);
|
||
Super::OnActivate();
|
||
}
|
||
//------------------------------------------------------------------------
|
||
void
|
||
ParticleRenderComponent::OnDeactivate()
|
||
{
|
||
if ( mParticleSystem.isvalid() )
|
||
{
|
||
mParticleSystem->DeActive();
|
||
}
|
||
|
||
_DeattachRenderObject();
|
||
DiscardRenderData();
|
||
Graphic::GraphicSystem::Instance()->m_BeforeDrawEvent -= Delegates::newDelegate(this, &ParticleRenderComponent::_updateTarget);
|
||
Super::OnDeactivate();
|
||
}
|
||
//------------------------------------------------------------------------
|
||
void
|
||
ParticleRenderComponent::OnDestroy()
|
||
{
|
||
if ( mParticleSystem.isvalid() && mParticleSystem->IsActive() )
|
||
{
|
||
mParticleSystem->DeActive();
|
||
}
|
||
mParticleSystem = NULL;
|
||
|
||
|
||
_DeattachRenderObject();
|
||
DiscardRenderData();
|
||
}
|
||
//------------------------------------------------------------------------
|
||
void ParticleRenderComponent::_OnMoveAfter()
|
||
{
|
||
if ( !mActor || !mParticleSystem.isvalid() )
|
||
return;
|
||
|
||
if ( !mActor || !mParticleSystem.isvalid() )
|
||
return;
|
||
|
||
//const Math::vector& wolrdPos = mActor->GetWorldPosition();
|
||
const Math::matrix44& worldMat = mActor->GetWorldTransform();
|
||
mParticleSystem->SetWorldMatrix(worldMat);
|
||
|
||
if (mRenderObject.isvalid())
|
||
{
|
||
mRenderObject->SetTransform(worldMat);
|
||
}
|
||
|
||
//if (mSimpleShape.isvalid())
|
||
//{
|
||
// mSimpleShape->SetTransform(worldMat);
|
||
//}
|
||
|
||
|
||
|
||
}
|
||
//------------------------------------------------------------------------
|
||
void
|
||
ParticleRenderComponent::_OnBeginFrame()
|
||
{
|
||
if ( !mParticleSystem.isvalid() )
|
||
return;
|
||
|
||
if ( mMeshInfo.dirty)
|
||
{
|
||
if (CheckMeshChanged() )
|
||
{
|
||
mIsBuild = false;
|
||
mIsAttached = false;
|
||
mMeshInfo.dirty = false;
|
||
_DeattachRenderObject();
|
||
}
|
||
}
|
||
|
||
//const GPtr<Actor>& pCamera = GraphicsFeature::Instance()->GetDefaultCameraActor();
|
||
// if ( pCamera.isvalid() )
|
||
// mParticleSystem->SetCameraMatrix( pCamera->GetWorldTransform() );
|
||
|
||
LoadEmitterMesh();
|
||
BuildRenderData();
|
||
mParticleSystem->SetParticleFPS(_fpsControl());
|
||
Super::_OnBeginFrame();
|
||
|
||
}
|
||
//------------------------------------------------------------------------
|
||
void
|
||
ParticleRenderComponent::OnParticleDataChange()
|
||
{
|
||
_DeattachRenderObject();
|
||
DiscardRenderData();
|
||
BuildRenderData();
|
||
}
|
||
//------------------------------------------------------------------------
|
||
bool ParticleRenderComponent::CheckMeshChanged(void)
|
||
{
|
||
if(mPrimitiveResInfo&& mPrimitiveResInfo->GetHandle().IsValid())
|
||
return true;
|
||
|
||
return false;
|
||
}
|
||
//--------------------------------------------------------------------------------
|
||
const GPtr<Resources::MeshRes> ParticleRenderComponent::GetMesh() const
|
||
{
|
||
if (!mPrimitiveResInfo || !mPrimitiveResInfo->GetRes().isvalid())
|
||
{
|
||
return NULL;
|
||
}
|
||
else
|
||
{
|
||
return mPrimitiveResInfo->GetRes().downcast<Resources::MeshRes>();
|
||
}
|
||
}
|
||
//--------------------------------------------------------------------------------
|
||
void ParticleRenderComponent::LoadEmitterMesh(void)
|
||
{
|
||
const GPtr<ParticleSystem>& parSystem = GetParticleSystem();
|
||
if ( !parSystem.isvalid() )
|
||
return;
|
||
|
||
|
||
// load modelEmitter 's meshres
|
||
if ( !parSystem->IsLoadEmitterMesh())
|
||
{
|
||
const GPtr<Particles::ParticleEmitter>& pEmit = parSystem->GetEmitter();
|
||
if( pEmit.isvalid() && pEmit->IsA( Particles::ModelEmitter::RTTI ) )
|
||
{
|
||
const GPtr<Particles::ModelEmitter>& pModelEmit = pEmit.downcast<Particles::ModelEmitter>();
|
||
|
||
const Resources::ResourceId& meshId= pModelEmit->GetMeshName();
|
||
if("" == meshId.AsString())
|
||
return;
|
||
if ( !mEmitMeshRes || mEmitMeshRes->GetResID() != meshId)
|
||
{
|
||
mEmitMeshRes = Resources::ResourceManager::Instance()->CreatePrimitiveInfo(meshId, Resources::ResourcePriority::MeshDefault);
|
||
}
|
||
|
||
if ( mEmitMeshRes->GetHandle().IsValid() )
|
||
{
|
||
pModelEmit->SetMeshRes(mEmitMeshRes->GetRes());
|
||
}
|
||
}
|
||
parSystem->SetLoadEmitterMesh(true);
|
||
}
|
||
}
|
||
//------------------------------------------------------------------------
|
||
void ParticleRenderComponent::BuildRenderData(void)
|
||
{
|
||
if ( mIsBuild )
|
||
return;
|
||
|
||
mRenderDates.Clear();
|
||
n_assert( mRenderDates.Size() == 0 );
|
||
|
||
const GPtr<ParticleSystem>& parSystem = GetParticleSystem();
|
||
if ( !parSystem.isvalid() )
|
||
return;
|
||
|
||
const GPtr<Particles::ParticleTarget>& pTarget = parSystem->GetTarget();
|
||
if( !pTarget.isvalid() )
|
||
return;
|
||
|
||
|
||
if ( pTarget->GetTargetType() == ParticleTarget::Mesh )
|
||
{
|
||
ResourceId& resId = mMeshInfo.meshID;
|
||
Resources::Priority priority = mMeshInfo.priority;
|
||
if ( !mPrimitiveResInfo.isvalid() || mPrimitiveResInfo->GetResID() != resId )
|
||
{
|
||
mPrimitiveResInfo = Resources::ResourceManager::Instance()->CreatePrimitiveInfo( resId, priority);
|
||
return;
|
||
}
|
||
|
||
if ( !mPrimitiveResInfo->GetHandle().IsValid() )
|
||
return;
|
||
|
||
const GPtr<Resources::Resource>& resource = mPrimitiveResInfo->GetRes();
|
||
|
||
if ( resource.isvalid() && resource->GetState() == Resource::Loaded )
|
||
{
|
||
const GPtr<Resources::MeshRes>& meshResource = resource.downcast<Resources::MeshRes>();
|
||
n_assert( meshResource.isvalid() );
|
||
|
||
SizeT subMeshCount = meshResource->GetSubMeshCount();
|
||
while ( mRenderableResUnitList.Size() < subMeshCount )
|
||
{
|
||
mRenderableResUnitList.Append(RenderbleResUnit());
|
||
mRenderableResUnitList.Back().CopyFrom( mRenderableResUnitList[0]);
|
||
}
|
||
|
||
Math::bbox box;
|
||
box.begin_extend();
|
||
SizeT curMat = 0;
|
||
for ( IndexT subIndex = 0 ; subIndex < subMeshCount; ++subIndex)
|
||
{
|
||
mRenderDates.Append( RenderData());
|
||
RenderData& renderData = mRenderDates.Back();
|
||
|
||
renderData.mPartType = (ushort)ParticleTarget::Mesh;
|
||
renderData.mPrimitiveHandle = mPrimitiveResInfo->GetHandle();
|
||
renderData.mSubmeshIndex = subIndex;
|
||
renderData.mTargetIndex = 0;
|
||
|
||
const SubMesh* subMesh = meshResource->GetSubMesh(subIndex);
|
||
RenderObjectType::RenderableType* renderable = mRenderableResUnitList[curMat].ResetRenderable<RenderObjectType::RenderableType>();
|
||
_SetRenderable( meshResource, curMat, renderable);
|
||
|
||
box.extend( subMesh->box );
|
||
++curMat;
|
||
}
|
||
box.end_extend();
|
||
const ParticleTargetPtr& target = mParticleSystem->GetTarget();
|
||
target.downcast<ParticleEntityTarget>()->_setMeshBox(box);
|
||
}
|
||
else
|
||
{
|
||
_DeattachRenderObject();
|
||
return;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
// just rebuild pool
|
||
int quota = parSystem->GetParticleQuota();
|
||
parSystem->_resetPool( quota );
|
||
|
||
mRenderDates.Append( RenderData() );
|
||
RenderData& renderData = mRenderDates[0];
|
||
//renderData.mPrimitiveGroup = PrimitiveGroup::Create();
|
||
renderData.mTargetIndex = 0;
|
||
renderData.mPartType = pTarget->GetTargetType();
|
||
//pTarget->SetPrimitiveGroup( renderData.mPrimitiveGroup );
|
||
pTarget->SetNeedPrimitive(true);
|
||
|
||
RenderObjectType::RenderableType* renderable = mRenderableResUnitList[0].ResetRenderable<RenderObjectType::RenderableType>();
|
||
_SetRenderable(NULL, 0, renderable);
|
||
}
|
||
|
||
//New RenderObject
|
||
if( !mRenderObject.isvalid() )
|
||
{
|
||
mRenderObject = RenderObjectType::Create();
|
||
}
|
||
mRenderObject->SetOwner(this);
|
||
mRenderObject->SetTransform(mActor->GetWorldTransform());
|
||
_AttachRenderObject();
|
||
mIsBuild = true;
|
||
}
|
||
//------------------------------------------------------------------------
|
||
void ParticleRenderComponent::DiscardRenderData(void)
|
||
{
|
||
//if ( !mIsBuild )
|
||
//{
|
||
// n_assert( mRenderDates.IsEmpty() );
|
||
// return;
|
||
//}
|
||
|
||
mIsBuild = false;
|
||
|
||
SizeT count = mRenderDates.Size();
|
||
for ( IndexT index = 0; index < mRenderDates.Size(); ++index )
|
||
{
|
||
RenderData& renderData = mRenderDates[index];
|
||
|
||
if ( renderData.mPrimitiveHandle.IsValid() )
|
||
{
|
||
//GraphicSystem::Instance()->RemovePrimitive( renderData.mPrimitiveHandle );
|
||
//GraphicObjectManager::Instance()->DiscardPrimitiveHandle( renderData.mPrimitiveHandle );
|
||
const ParticleTargetPtr& target = mParticleSystem->GetTarget();
|
||
if(target.isvalid())
|
||
target->SetDirtyPrim(true);
|
||
renderData.mPrimitiveHandle = RenderBase::PrimitiveHandle();
|
||
}
|
||
}
|
||
mRenderDates.Clear();
|
||
}
|
||
|
||
void ParticleRenderComponent::UpdateRenderLayer()
|
||
{
|
||
if (mRenderObject.isvalid())
|
||
{
|
||
mRenderObject->SetLayerID(mActor->GetLayerID());
|
||
}
|
||
}
|
||
|
||
void ParticleRenderComponent::SetVisible(bool bVis)
|
||
{
|
||
if ( bVis == mVisible )
|
||
{
|
||
return;
|
||
}
|
||
mVisible = bVis;
|
||
if (IsActive())
|
||
{
|
||
if (mVisible)
|
||
{
|
||
_AttachRenderObject();
|
||
}
|
||
else
|
||
{
|
||
_DeattachRenderObject();
|
||
}
|
||
}
|
||
}
|
||
#ifdef __GENESIS_EDITOR__
|
||
void ParticleRenderComponent::SetEditorVisible(bool bVis)
|
||
{
|
||
Super::SetEditorVisible(bVis);
|
||
if (IsActive())
|
||
{
|
||
mRenderObject->SetEditorVisible(bVis);
|
||
}
|
||
}
|
||
#endif
|
||
|
||
void ParticleRenderComponent::OnRenderSceneChanged()
|
||
{
|
||
if (mRenderObject.isvalid() && mRenderObject->Attached())
|
||
{
|
||
mRenderObject->Attach(mActor->GetRenderScene());
|
||
}
|
||
}
|
||
|
||
void ParticleRenderComponent::_AttachRenderObject()
|
||
{
|
||
|
||
if(!mVisible)
|
||
return;
|
||
if (mRenderObject.isvalid())
|
||
{
|
||
n_assert(mActor);
|
||
mRenderObject->Attach(mActor->GetRenderScene());
|
||
}
|
||
|
||
}
|
||
|
||
void ParticleRenderComponent::_DeattachRenderObject()
|
||
{
|
||
if (mRenderObject.isvalid())
|
||
{
|
||
n_assert(mActor);
|
||
mRenderObject->Detach();
|
||
}
|
||
|
||
}
|
||
void ParticleRenderComponent::_updateTarget( Graphic::Camera* camera )
|
||
{
|
||
if(mIsBuild)
|
||
{
|
||
mParticleSystem->SetCameraMatrix( camera->GetTransform());
|
||
mParticleSystem->_postProcessParticles();
|
||
UpdateRenderData();
|
||
}
|
||
mCurCamera = camera;
|
||
}
|
||
void ParticleRenderComponent::_SetRenderable(const GPtr<Resources::MeshRes>& meshRes, IndexT index, RenderObjectType::RenderableType* renderable)
|
||
{
|
||
if (meshRes.isvalid())
|
||
{
|
||
SubMesh* subMesh = meshRes->GetSubMesh(index);
|
||
n_assert(subMesh);
|
||
|
||
renderable->SetParticleRenderInfo(index,
|
||
subMesh->firstVertex,
|
||
subMesh->numVertex,
|
||
subMesh->FirstIndex,
|
||
subMesh->numIndex);
|
||
}
|
||
else
|
||
{
|
||
RenderData& renderdata = mRenderDates[index];
|
||
if ( renderdata.mPrimitiveHandle.IsValid())
|
||
{
|
||
const ParticleTargetPtr& target = mParticleSystem->GetTarget();
|
||
renderable->SetParticleRenderInfo(index,
|
||
0, target->GetActiveVertexCount(),
|
||
0, target->GetActiveIndexCount());
|
||
}
|
||
else
|
||
{
|
||
renderable->SetParticleRenderInfo(index, 0, 0, 0, 0);
|
||
}
|
||
}
|
||
}
|
||
void
|
||
ParticleRenderComponent::_UpdateRenderable(IndexT index, SizeT activeVertexCount, SizeT activeIndexCount, signed char sort, RenderObjectType::RenderableType* renderable)
|
||
{
|
||
renderable->SetParticleRenderInfo(index,
|
||
0, activeVertexCount,
|
||
0, activeIndexCount);
|
||
renderable->SetSort(sort);
|
||
}
|
||
//------------------------------------------------------------------------
|
||
void
|
||
ParticleRenderComponent::UpdateRenderData(void)
|
||
{
|
||
for ( IndexT index = 0; index < mRenderDates.Size(); ++index )
|
||
{
|
||
RenderData& renderData = mRenderDates[index];
|
||
RenderObjectType::RenderableType* renderable = mRenderableResUnitList[index].GetRenderableFast<RenderObjectType::RenderableType>();
|
||
|
||
if ( renderData.mPartType == ParticleTarget::Mesh )
|
||
{
|
||
const GPtr<ParticleSystem>& parSystem = GetParticleSystem();
|
||
if ( !parSystem.isvalid() )
|
||
return;
|
||
|
||
const ParticleTargetPtr& target = parSystem->GetTarget();
|
||
const GPtr<ParticleEntityTarget>& entityTarget = target.downcast<ParticleEntityTarget>();
|
||
|
||
if ( !entityTarget->IsNeedToRender() )
|
||
return;
|
||
|
||
GPtr<MeshRes> meshres = mPrimitiveResInfo->GetRes().downcast<MeshRes>();
|
||
|
||
if ( meshres.isvalid() && meshres->GetState() == Resource::Loaded )
|
||
{
|
||
SizeT vertexCount = meshres->GetVertexCount();
|
||
ColorData colorData;
|
||
Math::Color32 color(255,255,255,255);
|
||
|
||
ColorData::Elem* elem = meshres->GetVertexData<ColorData>();
|
||
|
||
if ( elem == NULL )
|
||
{
|
||
colorData.Fill(0, vertexCount, color );
|
||
if( !meshres->SetVertexData<ColorData>(&colorData[0], vertexCount ) )
|
||
return;
|
||
}
|
||
|
||
if ( !renderData.mPrimitiveHandle.IsValid() )
|
||
renderData.mPrimitiveHandle = mPrimitiveResInfo->GetHandle();
|
||
else
|
||
GraphicObjectManager::Instance()->UpdataPrimitiveHandle(meshres);
|
||
|
||
if( renderData.mSubmeshIndex >= meshres->GetSubMeshCount())
|
||
continue;
|
||
|
||
_SetRenderable(meshres, index, renderable);
|
||
}
|
||
|
||
}// end: if ( renderData.mPartType == ParticleTarget::Mesh )
|
||
else
|
||
{
|
||
const ParticleTargetPtr& target = mParticleSystem->GetTarget();
|
||
signed char sort = mParticleSystem->GetSort();
|
||
|
||
if (target.isvalid())
|
||
{
|
||
if (target->IsDirtyPrim())
|
||
{
|
||
renderData.mPrimitiveHandle = mParticleSystem->GetTarget()->GetPrimitiveHandle();
|
||
target->SetDirtyPrim(false);
|
||
}
|
||
_UpdateRenderable(index, target->GetActiveVertexCount(), target->GetActiveIndexCount(), sort, renderable);
|
||
}
|
||
else
|
||
{
|
||
_UpdateRenderable(index, 0, 0, sort, renderable);
|
||
}
|
||
|
||
}//end: if ( renderData.mPartType != ParticleTarget::Mesh )
|
||
|
||
}//end: for ( IndexT index = 0; index < mRenderDates.Size(); ++index )
|
||
if(mParticleSystem->_NeedUpdateBox())
|
||
{
|
||
mRenderObject->SetBoundingBox(mParticleSystem->GetBoundingBox());
|
||
}
|
||
}
|
||
//------------------------------------------------------------------------
|
||
void
|
||
ParticleRenderComponent::_OnFrame()
|
||
{
|
||
|
||
}
|
||
//------------------------------------------------------------------------
|
||
void ParticleRenderComponent::SetShaderMask()
|
||
{
|
||
SizeT sub_count = mRenderableResUnitList.Size();
|
||
for ( IndexT index = 0; index < sub_count; ++index )
|
||
{
|
||
Renderable* renderable = mRenderableResUnitList[index].GetRenderable();
|
||
|
||
if (renderable == NULL)
|
||
{
|
||
return;
|
||
}
|
||
const MaterialInstance* material_instance = renderable->GetMaterial();
|
||
{
|
||
const Util::Array< GPtr<MaterialPass> >& passList = material_instance->GetTech()->GetPassList();
|
||
|
||
//<2F><><EFBFBD><EFBFBD>forward pass <20><><EFBFBD>õ<EFBFBD><C3B5><EFBFBD> <20><>
|
||
const GPtr<MaterialPass>& pass = passList[eForward - 1];
|
||
const GPtr<ShaderProgramCompiler::ShaderMarcro>& pMarcro = pass->GetShaderMarcro();
|
||
pMarcro->Reset();
|
||
mParticleSystem->SetShaderMask(pMarcro);
|
||
renderable->SetShaderMask(eForward,pMarcro->GetShaderMask());
|
||
}
|
||
}
|
||
}
|
||
//------------------------------------------------------------------------
|
||
void ParticleRenderComponent::GetTargetInfo(ushort& partType,Util::Array<Math::matrix44>& mMats, Util::Array<Math::float4>& mColors)
|
||
{
|
||
const GPtr<ParticleSystem>& parSystem = GetParticleSystem();
|
||
if ( !parSystem.isvalid() )
|
||
return ;
|
||
|
||
const GPtr<Particles::ParticleTarget>& pTarget = parSystem->GetTarget();
|
||
if( !pTarget.isvalid() )
|
||
return ;
|
||
|
||
partType = pTarget->GetTargetType();
|
||
|
||
if ( partType == ParticleTarget::Mesh )
|
||
{
|
||
if(mMeshInfo.dirty || !mIsBuild)
|
||
return;
|
||
GPtr<Particles::ParticleEntityTarget> entityTar = pTarget.downcast<ParticleEntityTarget>();
|
||
|
||
mMats.AppendArray( entityTar->GetMatrixList());
|
||
mColors.AppendArray( entityTar->GetColorList());
|
||
}
|
||
else if ( partType == ParticleTarget::Decal )
|
||
{
|
||
GPtr<Particles::ParticleDecalTarget> decalTar = pTarget.downcast<ParticleDecalTarget>();
|
||
|
||
mMats.Append( decalTar->GetDecalRotation());
|
||
mColors.Append( Math::float4(1.0f,1.0f,1.0f,1.0f));
|
||
}
|
||
else
|
||
{
|
||
mMats.Append( Math::matrix44::identity());
|
||
mColors.Append( Math::float4(1.0f,1.0f,1.0f,1.0f));
|
||
}
|
||
}
|
||
|
||
//------------------------------------------------------------------------
|
||
void ParticleRenderComponent::CalculateBBox(Math::bbox& box,const Util::Array<Math::matrix44>& matlist)
|
||
{
|
||
SizeT PosIndex = 0;
|
||
while (PosIndex < matlist.Size())
|
||
{
|
||
Math::float4 curPos = matlist[PosIndex].get_position();
|
||
box.extend(curPos);
|
||
PosIndex++;
|
||
}
|
||
}
|
||
//--------------------------------------------------------------------------------
|
||
void ParticleRenderComponent::RemoveShader( IndexT iSubMesh )
|
||
{
|
||
if ( iSubMesh < 0 )
|
||
{
|
||
return;
|
||
}
|
||
|
||
//whether need to determine the render type is entity target
|
||
if ( iSubMesh >= mRenderableResUnitList.Size() )
|
||
{
|
||
// delete the renderable from graphic system
|
||
mRenderableResUnitList.EraseIndex(iSubMesh);
|
||
}
|
||
}
|
||
//------------------------------------------------------------------------
|
||
void
|
||
ParticleRenderComponent::SetParticleSystem( const GPtr<Particles::ParticleSystem>& parSystem )
|
||
{
|
||
if ( mParticleSystem == parSystem )
|
||
{
|
||
return;
|
||
}
|
||
|
||
if ( mParticleSystem.isvalid() )
|
||
{
|
||
if ( mParticleSystem->IsActive() )
|
||
{
|
||
mParticleSystem->DeActive();
|
||
}
|
||
}
|
||
|
||
mParticleSystem = parSystem;
|
||
|
||
if ( mParticleSystem.isvalid() )
|
||
{
|
||
if ( IsActive() )
|
||
{
|
||
mParticleSystem->Active();
|
||
}
|
||
}
|
||
|
||
OnParticleSystemChange();
|
||
}
|
||
//--------------------------------------------------------------------------------
|
||
void ParticleRenderComponent::SetEmitMeshRes(const Resources::ResourceId& meshID, int techIdx , int emitIdx )
|
||
{
|
||
|
||
const GPtr<ParticleSystem>& parSystem = GetParticleSystem();
|
||
if ( !parSystem.isvalid() )
|
||
return;
|
||
|
||
const GPtr<Particles::ParticleEmitter>& pEmit = parSystem->GetEmitter();
|
||
|
||
if( pEmit.isvalid() && pEmit->IsA( Particles::ModelEmitter::RTTI ) )
|
||
{
|
||
const GPtr<Particles::ModelEmitter>& pModelEmit = pEmit.downcast<Particles::ModelEmitter>();
|
||
pModelEmit->SetMeshName(meshID.AsString());
|
||
}
|
||
}
|
||
//------------------------------------------------------------------------
|
||
void
|
||
ParticleRenderComponent::OnParticleSystemChange()
|
||
{
|
||
if ( mActor )
|
||
{
|
||
GPtr<ParticleComponentChangeMsg> msg = ParticleComponentChangeMsg::Create();
|
||
mActor->SendSync( msg.upcast<Messaging::Message>() );
|
||
}
|
||
}
|
||
//------------------------------------------------------------------------
|
||
void ParticleRenderComponent::CopyFrom( const GPtr<Component>& pComponent )
|
||
{
|
||
if( !pComponent.isvalid() )
|
||
return;
|
||
if( !pComponent->GetRtti()->IsDerivedFrom( *(this->GetRtti()) ) )
|
||
return;
|
||
GPtr<ParticleRenderComponent> pSource = pComponent.downcast<ParticleRenderComponent>();
|
||
|
||
SetMeshID(pSource->GetMeshID(), pSource->GetMeshLoadPriority());
|
||
mTemplateName = pSource->GetTemplateID();
|
||
|
||
ParticleSystemPtr newPartSystem = ParticleSystem::Create();
|
||
newPartSystem->CopyFrom(pSource->GetParticleSystem());
|
||
SetParticleSystem(newPartSystem);
|
||
|
||
Super::CopyFrom( pComponent );
|
||
}
|
||
//------------------------------------------------------------------------------
|
||
void ParticleRenderComponent::GetReferenceResourceId(Util::Array<Resources::ReferenceResource>& list) const
|
||
{
|
||
if (mEmitMeshRes.isvalid())
|
||
{
|
||
list.Append(ReferenceResource(mEmitMeshRes->GetResID(), Resources::RR_Unknown));
|
||
}
|
||
|
||
list.Append(ReferenceResource(mTemplateName, Resources::RR_Unknown));
|
||
Super::GetReferenceResourceId(list);
|
||
}
|
||
//------------------------------------------------------------------------
|
||
void ParticleRenderComponent::SetMeshID(const Resources::ResourceId& meshID, Resources::Priority priority )
|
||
{
|
||
//if( mMeshInfo.meshID != meshID ) //<2F>ȼ<EFBFBD><C8BC><EFBFBD>
|
||
{
|
||
if (mActor && mActor->PriorityDefinition())
|
||
{
|
||
priority = mActor->GetPriority();
|
||
}
|
||
mMeshInfo.meshID = meshID;
|
||
mMeshInfo.priority = priority;
|
||
mMeshInfo.dirty = true;
|
||
}
|
||
|
||
}
|
||
//------------------------------------------------------------------------
|
||
void ParticleRenderComponent::SetTemplateID( const Resources::ResourceId& templateID )
|
||
{
|
||
mTemplateName = templateID;
|
||
}
|
||
//------------------------------------------------------------------------
|
||
const Resources::ResourceId& ParticleRenderComponent::GetTemplateID( void ) const
|
||
{
|
||
return mTemplateName;
|
||
}
|
||
//-------------------------------------------------------------------------
|
||
SizeT ParticleRenderComponent::_fpsControl()
|
||
{
|
||
Math::bbox box = mParticleSystem->GetBoundingBox();
|
||
Math::float4 boxSizeVec = box.pmax - box.pmin;
|
||
float boxSize = boxSizeVec.x()*boxSizeVec.x()+boxSizeVec.y()*boxSizeVec.y()+boxSizeVec.z()*boxSizeVec.z();
|
||
|
||
float minViewSize = 400000000;
|
||
|
||
if(!mActor)
|
||
{
|
||
return (SizeT)(minViewSize);
|
||
}
|
||
|
||
const Graphic::RenderScene* renderScene = mActor->GetRenderScene();
|
||
if(!renderScene)
|
||
{
|
||
return (SizeT)(minViewSize);
|
||
}
|
||
|
||
const Graphic::RenderScene::CameraList& cameraList = renderScene->GetCameraList();
|
||
for(IndexT cameraIndex = 0; cameraIndex < cameraList.Size(); cameraIndex++)
|
||
{
|
||
if(cameraList[cameraIndex])
|
||
{
|
||
Math::vector cameraLocalPos = cameraList[cameraIndex]->GetTransform().get_position() - mActor->GetWorldPosition();
|
||
float dis = cameraLocalPos.x()*cameraLocalPos.x()+cameraLocalPos.y()*cameraLocalPos.y()+cameraLocalPos.z()*cameraLocalPos.z();
|
||
|
||
float zNear = cameraList[cameraIndex]->GetCameraSetting().GetZNear();
|
||
float zFar = cameraList[cameraIndex]->GetCameraSetting().GetZFar();
|
||
float farWidth = cameraList[cameraIndex]->GetCameraSetting().GetFarWidth();
|
||
float farHeight = cameraList[cameraIndex]->GetCameraSetting().GetFarHeight();
|
||
float viewSize = dis/((zFar-zNear)*(zFar-zNear))*(farWidth*farWidth + farHeight*farHeight);
|
||
|
||
minViewSize = Math::n_min(viewSize,minViewSize);
|
||
}
|
||
}
|
||
float ratioInView = minViewSize/boxSize;
|
||
float MINTIME = 0.033f;
|
||
float MAXTIME = 0.33f;
|
||
float updateTime = MINTIME + (MAXTIME-MINTIME) * ratioInView * ParticleSystem::UpdateFactor;
|
||
updateTime = updateTime>MAXTIME?MAXTIME:updateTime;
|
||
|
||
return (SizeT)(1.0/updateTime);
|
||
}
|
||
}
|