genesis-3d_engine/Engine/app/apputil/manuresutil.cc
zhongdaohuan 6e8fbca745 genesis-3d engine version 1.3.
match the genesis editor version 1.3.0.653.
2014-05-05 14:50:33 +08:00

532 lines
13 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 "apputil/manuresutil.h"
#include "resource/resourceserver.h"
namespace AppUtil
{
using namespace Resources;
using namespace Util;
using namespace Math;
GPtr<Resources::Resource>
ManuResUtil::CreateManuResource( const Util::String& expectResID, const Core::Rtti* ResType)
{
if ( !ResourceServer::HasInstance() )
{
return GPtr<Resource>();
}
ResourceServer* resServer = ResourceServer::Instance();
String realID = expectResID;
{
IndexT i = 0;
while( resServer->HasResource( realID ) )
{
realID.Format( "%s_%i", expectResID.AsCharPtr(), i);
++i;
}
}
n_assert( !resServer->HasResource( realID ) );
GPtr<Resource> res = resServer->CreateOrGetResource(realID, ResType );
// ÉèÖÃΪÊÖ¶¯¼ÓÔØ
if ( res.isvalid() )
{
res->SetManuLoad(true);
}
return res;
}
//------------------------------------------------------------------------
GPtr<Resources::MeshRes>
ManuResUtil::CreateManuMesh( const Util::String& expectResID )
{
GPtr<Resources::Resource> pRes = CreateManuResource(expectResID, &MeshRes::RTTI );
if ( pRes.isvalid() )
{
GPtr<MeshRes> pMesh = pRes.downcast<MeshRes>();
n_assert( pMesh.isvalid() );
return pMesh;
}
else
{
return GPtr<MeshRes>();
}
}
//------------------------------------------------------------------------
GPtr<Resources::MeshRes>
ManuResUtil::CreateManuMesh_LineList( const Util::String& expectResID,
SizeT numVertex,
const Math::float3* position,
Math::Color32 color,
SizeT numIndex ,
const Index16Container::value_type* indicies )
{
GPtr<Resources::MeshRes> mesh = CreateManuMesh( expectResID );
if ( !mesh.isvalid() )
{
return GPtr<MeshRes>();
}
if ( ManuResUtil::SetMesh_LineList(mesh, numVertex, position, color, numIndex, indicies ) )
{
return mesh;
}
else
{
return GPtr<MeshRes>();
}
}
//------------------------------------------------------------------------
void
ManuResUtil::Build_Box(const Math::bbox& bb, PositionData& pos, Index16Container& indicies)
{
scalar minX = bb.pmin.x();
scalar minY = bb.pmin.y();
scalar minZ = bb.pmin.z();
scalar maxX = bb.pmax.x();
scalar maxY = bb.pmax.y();
scalar maxZ = bb.pmax.z();
// vertex
n_assert( pos.IsEmpty() );
pos.Reserve(36);
//pos.Append( Math::float3(minX, minY, minZ ) );//4
//pos.Append( Math::float3(minX, maxY, minZ ) );//0
//pos.Append( Math::float3(maxX, maxY, minZ ) );//3
//pos.Append( Math::float3(maxX, minY, minZ ) );//5
//pos.Append( Math::float3(minX, minY, maxZ ) );//7
//pos.Append( Math::float3(minX, maxY, maxZ ) );//1
//pos.Append( Math::float3(maxX, maxY, maxZ ) );//2
//pos.Append( Math::float3(maxX, minY, maxZ ) );//6
{
pos.Append( Math::float3(minX, maxY, minZ ) );//0
pos.Append( Math::float3(minX, maxY, maxZ ) );//1
pos.Append( Math::float3(maxX, maxY, maxZ ) );//2
pos.Append( Math::float3(maxX, maxY, minZ ) );//3
pos.Append( Math::float3(minX, minY, minZ ) );//4
pos.Append( Math::float3(maxX, minY, minZ ) );//5
pos.Append( Math::float3(maxX, minY, maxZ ) );//6
pos.Append( Math::float3(minX, minY, maxZ ) );//7
pos.Append( Math::float3(minX, maxY, minZ ) );//0
pos.Append( Math::float3(minX, minY, minZ ) );//4
pos.Append( Math::float3(minX, minY, maxZ ) );//7
pos.Append( Math::float3(minX, maxY, maxZ ) );//1
pos.Append( Math::float3(maxX, maxY, minZ ) );//3
pos.Append( Math::float3(maxX, maxY, maxZ ) );//2
pos.Append( Math::float3(maxX, minY, maxZ ) );//6
pos.Append( Math::float3(maxX, minY, minZ ) );//5
pos.Append( Math::float3(minX, maxY, maxZ ) );//1
pos.Append( Math::float3(minX, minY, maxZ ) );//7
pos.Append( Math::float3(maxX, minY, maxZ ) );//6
pos.Append( Math::float3(maxX, maxY, maxZ ) );//2
pos.Append( Math::float3(minX, maxY, minZ ) );//0
pos.Append( Math::float3(maxX, maxY, minZ ) );//3
pos.Append( Math::float3(maxX, minY, minZ ) );//5
pos.Append( Math::float3(minX, minY, minZ ) );//4
}
// index
n_assert( indicies.IsEmpty() );
indicies.Reserve( 36 );
// bottom
{
indicies.Append( 0 );
indicies.Append( 1 );
indicies.Append( 2 );
indicies.Append( 2 );
indicies.Append( 3 );
indicies.Append( 0 );
}
// top
{
indicies.Append( 4 );
indicies.Append( 5 );
indicies.Append( 6 );
indicies.Append( 6 );
indicies.Append( 7 );
indicies.Append( 4 );
}
// font
{
indicies.Append( 8 );
indicies.Append( 9 );
indicies.Append( 10 );
indicies.Append( 10 );
indicies.Append( 11 );
indicies.Append( 8 );
}
// back
{
indicies.Append( 12 );
indicies.Append( 13 );
indicies.Append( 14 );
indicies.Append( 14 );
indicies.Append( 15 );
indicies.Append( 12 );
}
// left
{
indicies.Append( 16 );
indicies.Append( 17 );
indicies.Append( 18 );
indicies.Append( 18 );
indicies.Append( 19 );
indicies.Append( 16 );
}
// right
{
indicies.Append( 20 );
indicies.Append( 21 );
indicies.Append( 22 );
indicies.Append( 22 );
indicies.Append( 23 );
indicies.Append( 20 );
}
}
//------------------------------------------------------------------------
void Build_LineList_Box(const Math::bbox& bb, PositionData& pos, Index16Container& indicies)
{
scalar minX = bb.pmin.x();
scalar minY = bb.pmin.y();
scalar minZ = bb.pmin.z();
scalar maxX = bb.pmax.x();
scalar maxY = bb.pmax.y();
scalar maxZ = bb.pmax.z();
// vertex
n_assert( pos.IsEmpty() );
pos.Reserve(8);
pos.Append( Math::float3(minX, minY, minZ ) );
pos.Append( Math::float3(minX, maxY, minZ ) );
pos.Append( Math::float3(maxX, maxY, minZ ) );
pos.Append( Math::float3(maxX, minY, minZ ) );
pos.Append( Math::float3(minX, minY, maxZ ) );
pos.Append( Math::float3(minX, maxY, maxZ ) );
pos.Append( Math::float3(maxX, maxY, maxZ ) );
pos.Append( Math::float3(maxX, minY, maxZ ) );
// index
n_assert( indicies.IsEmpty() );
indicies.Reserve( 24 );
// bottom
{
indicies.Append( 0 );
indicies.Append( 1 );
indicies.Append( 1 );
indicies.Append( 2 );
indicies.Append( 2 );
indicies.Append( 3 );
indicies.Append( 3 );
indicies.Append( 0 );
}
// top
{
indicies.Append( 4 );
indicies.Append( 5 );
indicies.Append( 5 );
indicies.Append( 6 );
indicies.Append( 6 );
indicies.Append( 7 );
indicies.Append( 7 );
indicies.Append( 4 );
}
// side
{
indicies.Append( 1 );
indicies.Append( 5 );
indicies.Append( 0 );
indicies.Append( 4 );
indicies.Append( 2 );
indicies.Append( 6 );
indicies.Append( 3 );
indicies.Append( 7 );
}
}
//------------------------------------------------------------------------
void
ManuResUtil::Build_Cone(Math::float3 inAxis, Resources::PositionData& position, Resources::Index16Container& indicies, Math::scalar sThickness, Math::scalar sHRatio)
{
position.Append(inAxis);
Math::matrix44 mat = Math::matrix44::identity() ;
mat.set_position(float4(inAxis.x(),inAxis.y(),inAxis.z(),1));
//add the cone
for (int j = 0;j<=36;j++)
{
mat = matrix44::rotationaxis( float4(inAxis.x(),
inAxis.y(),
inAxis.z(),
1.0),
j*10 / 57.3f ) ;
//--- vertext of the cone
Math::float4 _oriVec(sThickness+inAxis.x()*sHRatio,sThickness+inAxis.y()*sHRatio,sThickness+inAxis.z()*sHRatio , 0);
_oriVec = Math::matrix44::transform(mat,_oriVec);
position.Append(Math::float3(_oriVec.x(),_oriVec.y(),_oriVec.z()) );
if(j>35)
continue;
//add cone 1 triangle
indicies.Append(j+1);
indicies.Append(0);
indicies.Append(j+2);
}
}
//-------------------------------------------------------------------------
void
ManuResUtil::Build_Column(Math::float3 inAxis, Resources::PositionData& position, Resources::Index16Container& indicies, Math::scalar sThickness)
{
if (inAxis.x() == 0 && inAxis.y() == 0 && inAxis.z() == 0)
return;
//position.Append(inAxis);
int PosReady = position.Size();
Math::matrix44 mat = Math::matrix44::identity() ;
mat.set_position(float4(inAxis.x(),inAxis.y(),inAxis.z(),1));
//add the cone
for (int j = 0;j<=36;j++)
{
mat = matrix44::rotationaxis( float4(inAxis.x(),
inAxis.y(),
inAxis.z(),
1.0),
j*10 / 57.3f ) ;
//---- vertext of the column
Math::float4 _column(sThickness + inAxis.x(), sThickness + inAxis.y(), sThickness + inAxis.z(), 0);//Öù¸ß
_column = Math::matrix44::transform( mat,_column);
position.Append(Math::float3(_column.x(),_column.y(),_column.z()) );
//axis value (0,0,0)
scalar sx = _column.x()* (inAxis.x()>0.0f?0:1);
scalar sy = _column.y()* (inAxis.y()>0.0f?0:1);
scalar sz = _column.z()* (inAxis.z()>0.0f?0:1);
Math::float3 tmp(sx,sy,sz) ;
position.Append(tmp);
//draw the column ====
if(j>35)
continue;
//add colomn 2 triangles
indicies.Append(PosReady + j*2+1);
indicies.Append(PosReady + j*2);
indicies.Append(PosReady + j*2+2);
indicies.Append(PosReady + j*2+2);
indicies.Append(PosReady + j*2+3);
indicies.Append(PosReady + j*2+1);
}
}
//------------------------------------------------------------------------
GPtr<Resources::MeshRes>
ManuResUtil::CreateManuMesh_WithTopology( const Util::String& expectResID,
SizeT numVertex,
const Math::float3* position,
Math::Color32 color,
SizeT numIndex,
const Resources::Index16Container::value_type* indicies,
RenderBase::PrimitiveTopology::Code ptCode)
{
GPtr<Resources::MeshRes> mesh = CreateManuMesh( expectResID );
if ( !mesh.isvalid() )
{
return GPtr<MeshRes>();
}
if ( numVertex < 2 || numVertex > 65535 || position == NULL )
{
return GPtr<MeshRes>();
}
mesh->SetTopologyType( ptCode );
// set position
if( !mesh->SetVertexData<PositionData>(position, numVertex ) )
{
return GPtr<MeshRes>();
}
// set color
ColorData colorData;
colorData.Fill(0, numVertex, color );
if( !mesh->SetVertexData<ColorData>(&colorData[0], numVertex ) )
{
return GPtr<MeshRes>();
}
n_assert( indicies );
if ( !mesh->SetIndex16(indicies, numIndex ) )
{
return GPtr<MeshRes>();
}
// create submesh. must has submesh now
SubMesh subMesh;
subMesh.FirstIndex = 0;
subMesh.numIndex = numIndex;
subMesh.firstVertex = 0;
subMesh.numVertex = numVertex;
if ( !mesh->SetSubMesh(&subMesh,0 ) )
{
return GPtr<MeshRes>();
}
// set boundingbox
mesh->RecalculateBounds(true);
// set resource state
mesh->SetState(Resource::Loaded);
//-------
return mesh;
}
//------------------------------------------------------------------------
bool
ManuResUtil::SetMesh_LineList( GPtr<MeshRes>& mesh,
SizeT numVertex,
const Math::float3* position,
Math::Color32 color,
SizeT numIndex ,
const Resources::Index16Container::value_type* indicies )
{
if ( !mesh.isvalid() )
{
return false;
}
if ( numVertex < 2 || numVertex > 65535 || position == NULL )
{
return false;
}
if ( numIndex != 0 && indicies == NULL )
{
return false;
}
mesh->SetTopologyType( RenderBase::PrimitiveTopology::LineList );
// set position
if( !mesh->SetVertexData<PositionData>(position, numVertex ) )
{
return false;
}
// set color
ColorData colorData;
colorData.Fill(0, numVertex, color );
if( !mesh->SetVertexData<ColorData>(&colorData[0], numVertex ) )
{
return false;
}
// create index. must has index now
SizeT realIndexCount = 0;
if ( numIndex == 0 )
{
realIndexCount = (numVertex-1) * 2;
Index16Container indexArray;
indexArray.Resize( realIndexCount, 0 );
for ( IndexT index = 0; index < numVertex-1; ++index )
{
n_assert( index < 65535 );
indexArray[index*2] = (ushort)index;
indexArray[index*2 + 1 ] = (ushort)(index + 1);
}
if( !mesh->SetIndex16( &indexArray[0], realIndexCount) )
{
return false;
}
}
else
{
realIndexCount = numIndex;
n_assert( indicies );
if ( !mesh->SetIndex16(indicies, numIndex ) )
{
return false;
}
}
// set boundingbox
mesh->RecalculateBounds(true);
// set resource state
mesh->SetState(Resource::Loaded);
return true;
}
}