629 lines
20 KiB
C++
629 lines
20 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.
|
||
****************************************************************************/
|
||
#ifndef __PROJECTOR_COMMIT__
|
||
|
||
#include "stdneb.h"
|
||
#include "projectorcomponent.h"
|
||
#include "graphicfeature/graphicsfeatureprotocol.h"
|
||
#include "graphicfeature/graphicsfeature.h"
|
||
#include "rendersystem/RenderSystem.h"
|
||
#if __ANDROID__
|
||
#define ICE_NO_DLL
|
||
#include "OPCODEA/Opcode.h"
|
||
#elif __OSX__
|
||
#include "Opcode.h"
|
||
#elif __WIN32__
|
||
#include "Opcode/Opcode.h"
|
||
#endif
|
||
#include "graphicsystem/Projector/CollisionModelServer.h"
|
||
|
||
#include "app/graphicfeature/components/skinnedmeshrendercomponent.h"
|
||
#include "app/graphicfeature/components/projectorcomponent.h"
|
||
#include "app/graphicfeature/components/projectorrenderobject.h"
|
||
#include "resource/meshres.h"
|
||
#include "app/terrainfeature/components/TerrainRenderObject.h"
|
||
|
||
namespace App
|
||
{
|
||
using namespace Resources;
|
||
|
||
const char* DefaultMaterial = "sys:projector.material";
|
||
|
||
__ImplementClass(App::ProjectorRenderComponent, 'PCOM', App::RenderComponent);
|
||
|
||
ProjectorRenderComponent::ProjectorRenderComponent()
|
||
: mProjector(NULL),
|
||
mIsNeedUpdate(false),
|
||
mVertexLimit(4*1024),
|
||
mPrimitive(NULL),
|
||
mTerrainPrimitive(NULL)
|
||
#ifdef __GENESIS_EDITOR__ // edtior use
|
||
,mIsBrushHelper(false)
|
||
#endif
|
||
{
|
||
mProjector = Graphic::Projector::Create();
|
||
mAabb.begin_extend();
|
||
}
|
||
//--------------------------------------------------------------------------------
|
||
ProjectorRenderComponent::~ProjectorRenderComponent()
|
||
{
|
||
if (mProjector.isvalid())
|
||
{
|
||
mProjector = NULL;
|
||
}
|
||
}
|
||
//--------------------------------------------------------------------------------
|
||
void ProjectorRenderComponent::SetupCallbacks()
|
||
{
|
||
mActor->RegisterComponentCallback(this, BeginFrame);
|
||
mActor->RegisterComponentCallback(this, OnFrame);
|
||
mActor->RegisterComponentCallback(this, MoveAfter);
|
||
}
|
||
//--------------------------------------------------------------------------------
|
||
void ProjectorRenderComponent::SetupAcceptedMessages()
|
||
{
|
||
Super::SetupAcceptedMessages();
|
||
}
|
||
//--------------------------------------------------------------------------------
|
||
void ProjectorRenderComponent::HandleMessage(const GPtr<Messaging::Message>& msg)
|
||
{
|
||
Super::HandleMessage(msg);
|
||
}
|
||
//--------------------------------------------------------------------------------
|
||
void ProjectorRenderComponent::OnActivate()
|
||
{
|
||
Super::OnActivate();
|
||
|
||
if ( mActor )
|
||
{
|
||
mProjector->SetTransform( mActor->GetWorldTranslateRotation() );
|
||
}
|
||
|
||
if ( IsActive() )
|
||
{
|
||
_BuildRenderObject();
|
||
_AttachRenderObject();
|
||
}
|
||
|
||
}
|
||
//--------------------------------------------------------------------------------
|
||
void ProjectorRenderComponent::OnDeactivate()
|
||
{
|
||
Super::OnDeactivate();
|
||
|
||
if ( !IsActive())
|
||
{
|
||
_DeattachRenderObject();
|
||
}
|
||
if ( mPrimitive.IsValid() )
|
||
{
|
||
Graphic::GraphicSystem::Instance()->RemovePrimitive(mPrimitive);
|
||
mPrimitive = RenderBase::PrimitiveHandle();
|
||
}
|
||
|
||
if (mTerrainPrimitive)
|
||
{
|
||
Graphic::GraphicSystem::Instance()->RemovePrimitive(mTerrainPrimitive);
|
||
mTerrainPrimitive = RenderBase::PrimitiveHandle();
|
||
}
|
||
}
|
||
|
||
void ProjectorRenderComponent::UpdateRenderLayer()
|
||
{
|
||
if (mProjectorRenderObject.isvalid())
|
||
{
|
||
mProjectorRenderObject->SetLayerID(mActor->GetLayerID());
|
||
}
|
||
}
|
||
//--------------------------------------------------------------------------------
|
||
void ProjectorRenderComponent::_OnBeginFrame()
|
||
{
|
||
Super::_OnBeginFrame();
|
||
}
|
||
|
||
//--------------------------------------------------------------------------------
|
||
void ProjectorRenderComponent::_OnFrame()
|
||
{
|
||
#ifdef __GENESIS_EDITOR__
|
||
if(!mIsBrushHelper)
|
||
{
|
||
#endif
|
||
Update();
|
||
#ifdef __GENESIS_EDITOR__
|
||
}
|
||
#endif
|
||
}
|
||
//--------------------------------------------------------------------------------
|
||
void ProjectorRenderComponent::Update()
|
||
{
|
||
Super::_OnFrame();
|
||
if (mProjector.isvalid() && mIsNeedUpdate && m_bAllTexLoaded)
|
||
{
|
||
_UpdateProjector();
|
||
|
||
_BuildMeshInfo();
|
||
|
||
_BuildRenderable();
|
||
}
|
||
}
|
||
|
||
//--------------------------------------------------------------------------------
|
||
void ProjectorRenderComponent::_UpdateProjector()
|
||
{
|
||
// Rebuild mesh vertex container
|
||
mVertexs.Clear(false);
|
||
|
||
// Rebuild terrain vertex & indices container
|
||
mTerrainVertexs.Clear(false);
|
||
mTerrainIndices.Clear(false);
|
||
|
||
// Update shader param & retrieve render objects
|
||
mProjector->_UpdateProjector();
|
||
|
||
for(int matIndex=0;matIndex<GetMaterialCount();matIndex++)
|
||
{
|
||
GPtr<Graphic::MaterialInstance> instance = GetMaterial(matIndex);
|
||
instance->SetSort(Graphic::MatSort_ProjectorBegin+matIndex);
|
||
}
|
||
|
||
// Collision dealing
|
||
Math::matrix44 viewProjMatrix = Math::matrix44::zero();
|
||
Graphic::CollisionModelServer* collisionModelServer = Graphic::CollisionModelServer::Instance();
|
||
|
||
// TODO: Optimize usage of the following variables
|
||
Opcode::PlanesCollider planesCollider;
|
||
Opcode::PlanesCache planesCache;
|
||
IceMaths::Plane clipPlanes[6];
|
||
|
||
const Util::Array<GPtr<Graphic::RenderObject> >& renderObjs = mProjector->GetRenderObjs();
|
||
|
||
for (int i = 0; i < renderObjs.Size(); ++i)
|
||
{
|
||
// check ignore layer
|
||
if ( (1 << renderObjs[i]->GetLayerID() & mProjector->GetIgnoreLayers()) || !renderObjs[i]->GetProjected())
|
||
{
|
||
continue;
|
||
}
|
||
|
||
if ( renderObjs[i] && renderObjs[i]->GetRtti()->IsDerivedFrom(MeshRenderObject::RTTI)
|
||
&& !renderObjs[i]->GetRtti()->IsDerivedFrom(SkinnedRenderObject::RTTI)
|
||
#ifdef __GENESIS_EDITOR__
|
||
&& !mIsBrushHelper
|
||
#endif
|
||
)
|
||
{
|
||
GPtr<Graphic::RenderObject > renderObj = renderObjs[i];
|
||
|
||
// skip the subRenderObject such as axis_X etc
|
||
if ( renderObj->GetLayerID() == eSL_Assist )
|
||
continue;
|
||
|
||
GPtr<MeshRenderObject> meshRenderObj = renderObj.downcast<MeshRenderObject>();
|
||
n_assert(meshRenderObj);
|
||
|
||
// Get world matrix
|
||
const Math::matrix44& worldMatrix = meshRenderObj->GetTransform();
|
||
|
||
// Compute world-view-projection matrix
|
||
if ( viewProjMatrix == Math::matrix44::zero() )
|
||
{
|
||
viewProjMatrix = Math::matrix44::multiply(
|
||
mProjector->_CalcProjMatrix(),Math::matrix44::inverse(mProjector->GetTransform()));
|
||
}
|
||
Math::matrix44 worldViewProjMatrix = Math::matrix44::multiply(viewProjMatrix,worldMatrix);
|
||
|
||
// Get the collision mode
|
||
Util::StringAtom mesh = meshRenderObj->GetMeshName();
|
||
const GPtr<Graphic::CollisionModel>& collisionModel = collisionModelServer->GetCollisionModel( mesh.AsString() );
|
||
|
||
// Setup clip planes in model space, NB: Opcode use negative side as inside
|
||
// formula overturn : \\10.6.34.129\linuxsir\<5C><>ѵ<EFBFBD>ĵ<EFBFBD>\<5C><><EFBFBD><EFBFBD>\Graphics\Math\plane_extraction.pdf
|
||
clipPlanes[FRUSTUM_PLANE_LEFT].Set(
|
||
- worldViewProjMatrix[0][0] - worldViewProjMatrix[3][0],
|
||
- worldViewProjMatrix[0][1] - worldViewProjMatrix[3][1],
|
||
- worldViewProjMatrix[0][2] - worldViewProjMatrix[3][2],
|
||
- worldViewProjMatrix[0][3] - worldViewProjMatrix[3][3]);
|
||
clipPlanes[FRUSTUM_PLANE_RIGHT].Set(
|
||
+ worldViewProjMatrix[0][0] - worldViewProjMatrix[3][0],
|
||
+ worldViewProjMatrix[0][1] - worldViewProjMatrix[3][1],
|
||
+ worldViewProjMatrix[0][2] - worldViewProjMatrix[3][2],
|
||
+ worldViewProjMatrix[0][3] - worldViewProjMatrix[3][3]);
|
||
clipPlanes[FRUSTUM_PLANE_BOTTOM].Set(
|
||
- worldViewProjMatrix[1][0] - worldViewProjMatrix[3][0],
|
||
- worldViewProjMatrix[1][1] - worldViewProjMatrix[3][1],
|
||
- worldViewProjMatrix[1][2] - worldViewProjMatrix[3][2],
|
||
- worldViewProjMatrix[1][3] - worldViewProjMatrix[3][3]);
|
||
clipPlanes[FRUSTUM_PLANE_TOP].Set(
|
||
+ worldViewProjMatrix[1][0] - worldViewProjMatrix[3][0],
|
||
+ worldViewProjMatrix[1][1] - worldViewProjMatrix[3][1],
|
||
+ worldViewProjMatrix[1][2] - worldViewProjMatrix[3][2],
|
||
+ worldViewProjMatrix[1][3] - worldViewProjMatrix[3][3]);
|
||
clipPlanes[FRUSTUM_PLANE_NEAR].Set(
|
||
- worldViewProjMatrix[2][0] - worldViewProjMatrix[3][0],
|
||
- worldViewProjMatrix[2][1] - worldViewProjMatrix[3][1],
|
||
- worldViewProjMatrix[2][2] - worldViewProjMatrix[3][2],
|
||
- worldViewProjMatrix[2][3] - worldViewProjMatrix[3][3]);
|
||
clipPlanes[FRUSTUM_PLANE_FAR].Set(
|
||
+ worldViewProjMatrix[2][0] - worldViewProjMatrix[3][0],
|
||
+ worldViewProjMatrix[2][1] - worldViewProjMatrix[3][1],
|
||
+ worldViewProjMatrix[2][2] - worldViewProjMatrix[3][2],
|
||
+ worldViewProjMatrix[2][3] - worldViewProjMatrix[3][3]);
|
||
|
||
if (!planesCollider.Collide( planesCache, clipPlanes, 6, collisionModel->GetOpCodeModel(), NULL))
|
||
continue;
|
||
|
||
const uint* triangles = planesCollider.GetTouchedPrimitives();
|
||
const uint numTriangles = planesCollider.GetNbTouchedPrimitives();
|
||
|
||
if (!triangles || !numTriangles)
|
||
continue;
|
||
|
||
// Get the view vector base on projection type
|
||
Math::float4 vv;
|
||
Math::matrix44 eyeToModel = Math::matrix44::inverse(Math::matrix44::multiply( Math::matrix44::inverse(mProjector->GetTransform()), worldMatrix));
|
||
|
||
if ( mProjector->GetViewType() == Graphic::Projector::VT_Persp )
|
||
{
|
||
// Use view position as view vector
|
||
vv[0] = eyeToModel[0][3];
|
||
vv[1] = eyeToModel[1][3];
|
||
vv[2] = eyeToModel[2][3];
|
||
vv[3] = eyeToModel[3][3];
|
||
}
|
||
else
|
||
{
|
||
// Use view direction as view vector
|
||
vv[0] = eyeToModel[0][2];
|
||
vv[1] = eyeToModel[1][2];
|
||
vv[2] = eyeToModel[2][2];
|
||
vv[3] = eyeToModel[3][2];
|
||
}
|
||
|
||
const Util::Array<Math::float4>& faceNormals = collisionModel->GetFaceNormals();
|
||
const Util::Array<Math::float3>& vertices = collisionModel->GetVertices();
|
||
const Util::Array<uint>& indices = collisionModel->GetIndices();
|
||
SizeT vertexStart = mVertexs.Size();
|
||
SizeT vertexCount = 0;
|
||
SizeT cullCount = 0;
|
||
|
||
|
||
// Reserve memory avoid allocate overhead
|
||
mVertexs.Reserve(vertexStart + numTriangles*3);
|
||
|
||
for (uint i = 0; i < numTriangles; ++i)
|
||
{
|
||
uint triangleIndex = triangles[i];
|
||
Math::float4 faceNormal = Math::float4::normalize(faceNormals[triangleIndex]);
|
||
faceNormal.set_w(0.0f);
|
||
// check the triangle is projector facing
|
||
if ( ! Math::n_fequal(Math::float4::dot4(faceNormal,vv), 0.0f, 0.001f) )
|
||
{
|
||
Math::float3 tempPos;
|
||
Math::float4 result;
|
||
// transform vertex from model space to world space
|
||
for (int i = 0; i < 3; ++i,++vertexCount)
|
||
{
|
||
int index = triangleIndex*3 + i;
|
||
|
||
tempPos = vertices[indices[index]];
|
||
result = Math::matrix44::transform(worldMatrix,Math::float4(tempPos.x(),tempPos.y(),tempPos.z(),1.0f));
|
||
|
||
tempPos.x() = result.x();
|
||
tempPos.y() = result.y();
|
||
tempPos.z() = result.z();
|
||
|
||
mVertexs.Append(tempPos);
|
||
|
||
_UpdateBoundingBox(tempPos);
|
||
|
||
}
|
||
}
|
||
}
|
||
|
||
// Check vertex limit
|
||
n_assert(vertexStart <= mVertexLimit);
|
||
if ( mVertexLimit <= vertexStart )
|
||
break; // Just for safely
|
||
|
||
// check overrun
|
||
bool overrun = vertexStart + vertexCount > mVertexLimit;
|
||
if (overrun)
|
||
{
|
||
// discard overrun vertices
|
||
vertexCount = (mVertexLimit - vertexStart)/ 3 * 3;
|
||
mVertexs.Resize(vertexStart + vertexCount,Math::float3(0.0, 0.0, 0.0));
|
||
}
|
||
|
||
// No more process because vertices overrun
|
||
if (overrun)
|
||
break;
|
||
|
||
}
|
||
else if ( renderObjs[i]->GetRtti()->IsDerivedFrom(TerrainRenderObject::RTTI))
|
||
{
|
||
GPtr<TerrainRenderObject> terrainRenderObject = renderObjs[i].downcast<TerrainRenderObject>();
|
||
n_assert(terrainRenderObject.isvalid());
|
||
|
||
|
||
// catch indices
|
||
Resources::Index16Container::value_type* pIndices = terrainRenderObject->GetTerrainNodeIndexData();
|
||
SizeT indicesCount = terrainRenderObject->GetTerrainNodeIndexDataCount();
|
||
SizeT positionCount = mTerrainVertexs.Size();
|
||
for (int i = 0 ; i < indicesCount; ++i)
|
||
{
|
||
mTerrainIndices.Append(pIndices[i] + positionCount);
|
||
}
|
||
|
||
// catch position
|
||
const Resources::PositionData::Elem* pLocalPosition = terrainRenderObject->GetTerrainNodePosData();
|
||
SizeT positionsCount = terrainRenderObject->GetTerrainNodePosCount();
|
||
for ( int i = 0; i < positionsCount; ++i)
|
||
{
|
||
const Math::float3 worldPostion = pLocalPosition[i].transformPoint(terrainRenderObject->GetTransform());
|
||
mTerrainVertexs.Append(worldPostion);
|
||
_UpdateBoundingBox(worldPostion);
|
||
}
|
||
|
||
} // end handling each render object
|
||
|
||
} // end foreach render object
|
||
}
|
||
//--------------------------------------------------------------------------------
|
||
void ProjectorRenderComponent::_UpdateBoundingBox( const Math::float3 &pos)
|
||
{
|
||
mAabb.extend(Math::float4(pos.x(),pos.y(),pos.z(),1.0f));
|
||
}
|
||
//--------------------------------------------------------------------------------
|
||
void ProjectorRenderComponent::SetProjectorTrans(const Math::matrix44& trans)
|
||
{
|
||
if (mProjector.isvalid())
|
||
{
|
||
mProjector->SetTransform(trans);
|
||
}
|
||
}
|
||
|
||
//--------------------------------------------------------------------------------
|
||
Math::scalar ProjectorRenderComponent::GetAlphaValue(Math::scalar u, Math::scalar v)
|
||
{
|
||
if (GetMaterial(0).isvalid())
|
||
{
|
||
GPtr<Resources::Resource> pRes = GetMaterial(0)->GetTextureResInfo(0)->GetRes();
|
||
n_assert(pRes.isvalid());
|
||
GPtr<Resources::ImageRes> pImageRes = pRes.downcast<Resources::ImageRes>();
|
||
Math::scalar alpha = pImageRes->GetAlphaValue(u, v);
|
||
|
||
return alpha;
|
||
}
|
||
else
|
||
{
|
||
return 0.0f;
|
||
}
|
||
}
|
||
//--------------------------------------------------------------------------------
|
||
void ProjectorRenderComponent::ActiveProjector(bool enable)
|
||
{
|
||
EnableProjectorUpdate(enable);
|
||
}
|
||
|
||
//--------------------------------------------------------------------------------
|
||
const bool ProjectorRenderComponent::IsProjectorEnabled() const
|
||
{
|
||
return mIsNeedUpdate;
|
||
}
|
||
//--------------------------------------------------------------------------------
|
||
void ProjectorRenderComponent::_BuildRenderable()
|
||
{
|
||
n_assert( mActor );
|
||
|
||
_BuildRenderObject();
|
||
|
||
// Generate and fill renderable
|
||
if ( mProjectorRenderObject.isvalid() && mPrimitive.IsValid() )
|
||
{
|
||
// Mesh
|
||
mRenderableResUnitList[0].ResetRenderable<AppRenderable>();
|
||
AppRenderable* renderable = mRenderableResUnitList[0].GetRenderableFast<AppRenderable>();
|
||
renderable->SetRenderInfo( 0, mVertexs.Size(), 0, 0);
|
||
}
|
||
|
||
if (mProjectorRenderObject.isvalid() && mTerrainPrimitive.IsValid() )
|
||
{
|
||
// Terrain
|
||
mRenderableResUnitList[1].ResetRenderable<AppRenderable>();
|
||
AppRenderable* renderable = mRenderableResUnitList[1].GetRenderableFast<AppRenderable>();
|
||
renderable->SetRenderInfo( 0, mTerrainVertexs.Size(), 0, mTerrainIndices.Size());
|
||
}
|
||
}
|
||
//--------------------------------------------------------------------------------
|
||
void ProjectorRenderComponent::_BuildRenderObject()
|
||
{
|
||
// Generate new render object
|
||
if ( !mProjectorRenderObject.isvalid() )
|
||
{
|
||
mProjectorRenderObject = ProjectorRenderObject::Create();
|
||
mProjectorRenderObject->SetOwner(this);
|
||
mProjectorRenderObject->SetTransform(Math::matrix44::identity());
|
||
}
|
||
mProjectorRenderObject->SetBoundingBox(mAabb);
|
||
|
||
mAabb.begin_extend();
|
||
}
|
||
//--------------------------------------------------------------------------------
|
||
void ProjectorRenderComponent::OnRenderSceneChanged()
|
||
{
|
||
if (mProjectorRenderObject.isvalid() && mProjectorRenderObject->Attached())
|
||
{
|
||
mProjectorRenderObject->Attach(mActor->GetRenderScene());
|
||
}
|
||
}
|
||
//--------------------------------------------------------------------------------
|
||
void ProjectorRenderComponent::_AttachRenderObject()
|
||
{
|
||
if (mProjectorRenderObject.isvalid())
|
||
{
|
||
n_assert(mActor);
|
||
Graphic::RenderScene* rs = mActor->GetRenderScene();
|
||
mProjector->SetRenderScene(rs);
|
||
mProjectorRenderObject->Attach(rs);
|
||
}
|
||
}
|
||
//--------------------------------------------------------------------------------
|
||
void ProjectorRenderComponent::_DeattachRenderObject()
|
||
{
|
||
if ( mProjectorRenderObject.isvalid() )
|
||
{
|
||
mProjector->SetRenderScene(NULL);
|
||
mProjectorRenderObject->Detach();
|
||
}
|
||
}
|
||
//--------------------------------------------------------------------------------
|
||
void ProjectorRenderComponent::_BuildMeshInfo()
|
||
{
|
||
using namespace RenderBase;
|
||
|
||
// Mesh Use
|
||
if ( mVertexs.Size() )
|
||
{
|
||
Graphic::VertexBufferData2 vbd2;
|
||
vbd2.GetVertexComponents().Append(
|
||
RenderBase::VertexComponent(RenderBase::VertexComponent::Position,0, RenderBase::VertexComponent::Float3)); // layout
|
||
|
||
vbd2.Setup(mVertexs.Size(), sizeof(Math::float3), RenderBase::BufferData::Static, PrimitiveTopology::TriangleList, true);
|
||
vbd2.SetVertices(&mVertexs[0], mVertexs.Size());
|
||
if (mPrimitive.IsValid())
|
||
{
|
||
Graphic::GraphicSystem::Instance()->ChangePrimitiveHandle(mPrimitive, &vbd2, NULL);
|
||
}
|
||
else
|
||
{
|
||
mPrimitive = Graphic::GraphicSystem::Instance()->CreatePrimitiveHandle(&vbd2, NULL);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
// No points found
|
||
Graphic::GraphicSystem::Instance()->RemovePrimitive(mPrimitive);
|
||
mPrimitive = RenderBase::PrimitiveHandle();
|
||
}
|
||
|
||
// Terrain use
|
||
if ( mTerrainVertexs.Size() && mTerrainIndices.Size() )
|
||
{
|
||
Graphic::VertexBufferData2 vbd2;
|
||
vbd2.GetVertexComponents().Append(
|
||
RenderBase::VertexComponent(RenderBase::VertexComponent::Position,0, RenderBase::VertexComponent::Float3)); // layout
|
||
|
||
vbd2.Setup(mTerrainVertexs.Size(), sizeof(Math::float3), RenderBase::BufferData::Static, PrimitiveTopology::TriangleList, true);
|
||
vbd2.SetVertices(&mTerrainVertexs[0], mTerrainVertexs.Size());
|
||
|
||
|
||
Graphic::IndexBufferData2 ibd2;
|
||
ibd2.Setup(mTerrainIndices.Size(), RenderBase::BufferData::Static, RenderBase::IndexBufferData::Int16, true);
|
||
ibd2.SetIndices(&mTerrainIndices[0], mTerrainIndices.Size());
|
||
|
||
if (mTerrainPrimitive.IsValid())
|
||
{
|
||
Graphic::GraphicSystem::Instance()->ChangePrimitiveHandle(mTerrainPrimitive, &vbd2, &ibd2);
|
||
}
|
||
else
|
||
{
|
||
mTerrainPrimitive = Graphic::GraphicSystem::Instance()->CreatePrimitiveHandle(&vbd2, &ibd2);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
// No terrain found
|
||
Graphic::GraphicSystem::Instance()->RemovePrimitive(mTerrainPrimitive);
|
||
mTerrainPrimitive = NULL;
|
||
}
|
||
}
|
||
//--------------------------------------------------------------------------------
|
||
const RenderBase::PrimitiveHandle& ProjectorRenderComponent::GetPrimitiveHandleByRenderable( const Graphic::Renderable* renderable ) const
|
||
{
|
||
if ( renderable == mRenderableResUnitList[0].GetRenderableFast<AppRenderable>() )
|
||
{
|
||
return mPrimitive;
|
||
}
|
||
else
|
||
{
|
||
return mTerrainPrimitive;
|
||
}
|
||
}
|
||
//--------------------------------------------------------------------------------
|
||
void ProjectorRenderComponent::EnableProjectorUpdate(bool bEnable)
|
||
{
|
||
mIsNeedUpdate = bEnable;
|
||
|
||
if (bEnable)
|
||
{
|
||
_AttachRenderObject();
|
||
}
|
||
else
|
||
{
|
||
_DeattachRenderObject();
|
||
}
|
||
}
|
||
//--------------------------------------------------------------------------------
|
||
void ProjectorRenderComponent::_OnMoveAfter()
|
||
{
|
||
if ( mActor )
|
||
{
|
||
mProjector->SetTransform( mActor->GetWorldTranslateRotation() );
|
||
}
|
||
}
|
||
//--------------------------------------------------------------------------------
|
||
void ProjectorRenderComponent::CopyFrom( const GPtr<Component>& pComponent )
|
||
{
|
||
if( !pComponent.isvalid() )
|
||
return;
|
||
if( !pComponent->GetRtti()->IsDerivedFrom( *(this->GetRtti()) ) )
|
||
return;
|
||
|
||
GPtr<ProjectorRenderComponent> pSource = pComponent.downcast<ProjectorRenderComponent>();
|
||
// copy component data
|
||
mIsNeedUpdate = pSource->mIsNeedUpdate;
|
||
SetMaterialID(0, pSource->GetMaterialID(0), false);
|
||
|
||
// copy projector data
|
||
GPtr<Graphic::Projector> pSourceProjector = pSource->GetProJector();
|
||
n_assert( pSource->mProjector.isvalid() );
|
||
mProjector->CopyParam(pSourceProjector);
|
||
}
|
||
//--------------------------------------------------------------------------------
|
||
#ifdef __GENESIS_EDITOR__ // edtior use
|
||
bool ProjectorRenderComponent::GetBrushState() const
|
||
{
|
||
return mIsBrushHelper;
|
||
}
|
||
//--------------------------------------------------------------------------------
|
||
void ProjectorRenderComponent::SetBrushState( const bool b )
|
||
{
|
||
mIsBrushHelper = b;
|
||
}
|
||
|
||
#endif
|
||
//--------------------------------------------------------------------------------
|
||
|
||
}
|
||
#endif // __PROJECTOR_COMMIT__
|