2019-12-12 17:32:41 +01:00
// Copyright (C) 2014 Lauri Kasanen
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
# include "IrrCompileConfig.h"
# ifdef _IRR_COMPILE_WITH_B3D_WRITER_
# include "CB3DMeshWriter.h"
2023-08-15 00:01:22 +02:00
# include "SB3DStructs.h"
2019-12-12 17:32:41 +01:00
# include "os.h"
# include "ISkinnedMesh.h"
# include "IMeshBuffer.h"
# include "IWriteFile.h"
# include "ITexture.h"
# include "irrMap.h"
namespace irr
{
namespace scene
{
using namespace core ;
using namespace video ;
CB3DMeshWriter : : CB3DMeshWriter ( )
{
# ifdef _DEBUG
setDebugName ( " CB3DMeshWriter " ) ;
# endif
}
//! Returns the type of the mesh writer
EMESH_WRITER_TYPE CB3DMeshWriter : : getType ( ) const
{
return EMWT_B3D ;
}
//! writes a mesh
bool CB3DMeshWriter : : writeMesh ( io : : IWriteFile * file , IMesh * const mesh , s32 flags )
{
if ( ! file | | ! mesh )
return false ;
# ifdef __BIG_ENDIAN__
os : : Printer : : log ( " B3D export does not support big-endian systems. " , ELL_ERROR ) ;
return false ;
# endif
file - > write ( " BB3D " , 4 ) ;
2020-04-27 22:52:21 +02:00
file - > write ( " size " , 4 ) ; // BB3D chunk size, updated later
2019-12-12 17:32:41 +01:00
2020-04-27 22:52:21 +02:00
const u32 version = 1 ;
file - > write ( & version , 4 ) ;
2019-12-12 17:32:41 +01:00
//
2020-04-27 22:52:21 +02:00
const u32 numMeshBuffers = mesh - > getMeshBufferCount ( ) ;
2019-12-12 17:32:41 +01:00
array < SB3dTexture > texs ;
map < ITexture * , u32 > tex2id ; // TODO: texture pointer as key not sufficient as same texture can have several id's
u32 texsizes = 0 ;
2020-04-27 22:52:21 +02:00
for ( u32 i = 0 ; i < numMeshBuffers ; i + + )
2019-12-12 17:32:41 +01:00
{
const IMeshBuffer * const mb = mesh - > getMeshBuffer ( i ) ;
const SMaterial & mat = mb - > getMaterial ( ) ;
for ( u32 j = 0 ; j < MATERIAL_MAX_TEXTURES ; j + + )
{
if ( mat . getTexture ( j ) )
{
SB3dTexture t ;
t . TextureName = core : : stringc ( mat . getTexture ( j ) - > getName ( ) . getPath ( ) ) ;
// TODO: need some description of Blitz3D texture-flags to figure this out. But Blend should likely depend on material-type.
t . Flags = j = = 2 ? 65536 : 1 ;
t . Blend = 2 ;
// TODO: evaluate texture matrix
t . Xpos = 0 ;
t . Ypos = 0 ;
t . Xscale = 1 ;
t . Yscale = 1 ;
t . Angle = 0 ;
texs . push_back ( t ) ;
texsizes + = 7 * 4 + t . TextureName . size ( ) + 1 ;
tex2id [ mat . getTexture ( j ) ] = texs . size ( ) - 1 ;
}
}
}
2020-04-27 22:52:21 +02:00
file - > write ( " TEXS " , 4 ) ;
file - > write ( & texsizes , 4 ) ;
2019-12-12 17:32:41 +01:00
u32 numTexture = texs . size ( ) ;
for ( u32 i = 0 ; i < numTexture ; i + + )
{
2022-05-13 16:56:22 +02:00
file - > write ( texs [ i ] . TextureName . c_str ( ) , ( size_t ) texs [ i ] . TextureName . size ( ) + 1 ) ;
2020-04-27 22:52:21 +02:00
file - > write ( & texs [ i ] . Flags , 7 * 4 ) ;
2019-12-12 17:32:41 +01:00
}
//
2020-04-27 22:52:21 +02:00
file - > write ( " BRUS " , 4 ) ;
const u32 brushSizeAdress = file - > getPos ( ) ;
file - > write ( & brushSizeAdress , 4 ) ; // BRUSH chunk size, updated later
2019-12-12 17:32:41 +01:00
const u32 usedtex = MATERIAL_MAX_TEXTURES ;
2020-04-27 22:52:21 +02:00
file - > write ( & usedtex , 4 ) ;
2019-12-12 17:32:41 +01:00
2020-04-27 22:52:21 +02:00
for ( u32 i = 0 ; i < numMeshBuffers ; i + + )
2019-12-12 17:32:41 +01:00
{
const IMeshBuffer * const mb = mesh - > getMeshBuffer ( i ) ;
const SMaterial & mat = mb - > getMaterial ( ) ;
2020-04-27 22:52:21 +02:00
file - > write ( " " , 1 ) ;
2019-12-12 17:32:41 +01:00
float f = 1 ;
2020-04-27 22:52:21 +02:00
file - > write ( & f , 4 ) ;
file - > write ( & f , 4 ) ;
file - > write ( & f , 4 ) ;
file - > write ( & f , 4 ) ;
2019-12-12 17:32:41 +01:00
f = 0 ;
2020-04-27 22:52:21 +02:00
file - > write ( & f , 4 ) ;
2019-12-12 17:32:41 +01:00
u32 tmp = 1 ;
2020-04-27 22:52:21 +02:00
file - > write ( & tmp , 4 ) ;
2019-12-12 17:32:41 +01:00
tmp = 0 ;
2020-04-27 22:52:21 +02:00
file - > write ( & tmp , 4 ) ;
2019-12-12 17:32:41 +01:00
for ( u32 j = 0 ; j < MATERIAL_MAX_TEXTURES ; j + + )
{
2020-04-27 22:52:21 +02:00
s32 id = - 1 ;
2019-12-12 17:32:41 +01:00
if ( mat . getTexture ( j ) )
{
2020-04-27 22:52:21 +02:00
id = tex2id [ mat . getTexture ( j ) ] ;
2019-12-12 17:32:41 +01:00
}
2020-04-27 22:52:21 +02:00
file - > write ( & id , 4 ) ;
2019-12-12 17:32:41 +01:00
}
}
2020-04-27 22:52:21 +02:00
writeSizeFrom ( file , brushSizeAdress + 4 , brushSizeAdress ) ; // BRUSH chunk size
2019-12-12 17:32:41 +01:00
2020-04-27 22:52:21 +02:00
file - > write ( " NODE " , 4 ) ;
u32 nodeSizeAdress = file - > getPos ( ) ;
file - > write ( & nodeSizeAdress , 4 ) ; // NODE chunk size, updated later
2019-12-12 17:32:41 +01:00
2020-04-27 22:52:21 +02:00
// Node
file - > write ( " " , 1 ) ;
2019-12-12 17:32:41 +01:00
2020-04-27 22:52:21 +02:00
// position
writeVector3 ( file , core : : vector3df ( 0.f , 0.f , 0.f ) ) ;
2019-12-12 17:32:41 +01:00
2020-04-27 22:52:21 +02:00
// scale
writeVector3 ( file , core : : vector3df ( 1.f , 1.f , 1.f ) ) ;
2019-12-12 17:32:41 +01:00
2020-04-27 22:52:21 +02:00
// rotation
writeQuaternion ( file , core : : quaternion ( 0.f , 0.f , 0.f , 1.f ) ) ;
2019-12-12 17:32:41 +01:00
// Mesh
2020-04-27 22:52:21 +02:00
file - > write ( " MESH " , 4 ) ;
const u32 meshSizeAdress = file - > getPos ( ) ;
file - > write ( & meshSizeAdress , 4 ) ; // MESH chunk size, updated later
2019-12-12 17:32:41 +01:00
s32 brushID = - 1 ;
2020-04-27 22:52:21 +02:00
file - > write ( & brushID , 4 ) ;
2019-12-12 17:32:41 +01:00
// Verts
2020-04-27 22:52:21 +02:00
file - > write ( " VRTS " , 4 ) ;
const u32 verticesSizeAdress = file - > getPos ( ) ;
file - > write ( & verticesSizeAdress , 4 ) ;
2019-12-12 17:32:41 +01:00
2020-04-27 22:52:21 +02:00
u32 flagsB3D = 3 ; // 1=normal values present, 2=rgba values present
file - > write ( & flagsB3D , 4 ) ;
2019-12-12 17:32:41 +01:00
2020-04-27 22:52:21 +02:00
const u32 texcoordsCount = getUVlayerCount ( mesh ) ;
file - > write ( & texcoordsCount , 4 ) ;
2019-12-12 17:32:41 +01:00
flagsB3D = 2 ;
2020-04-27 22:52:21 +02:00
file - > write ( & flagsB3D , 4 ) ;
2019-12-12 17:32:41 +01:00
2020-04-27 22:52:21 +02:00
for ( u32 i = 0 ; i < numMeshBuffers ; i + + )
2019-12-12 17:32:41 +01:00
{
const IMeshBuffer * const mb = mesh - > getMeshBuffer ( i ) ;
2020-04-27 22:52:21 +02:00
const u32 numVertices = mb - > getVertexCount ( ) ;
2019-12-12 17:32:41 +01:00
for ( u32 j = 0 ; j < numVertices ; j + + )
{
const vector3df & pos = mb - > getPosition ( j ) ;
2020-04-27 22:52:21 +02:00
writeVector3 ( file , pos ) ;
2019-12-12 17:32:41 +01:00
const vector3df & n = mb - > getNormal ( j ) ;
2020-04-27 22:52:21 +02:00
writeVector3 ( file , n ) ;
2019-12-12 17:32:41 +01:00
switch ( mb - > getVertexType ( ) )
{
case EVT_STANDARD :
{
S3DVertex * v = ( S3DVertex * ) mb - > getVertices ( ) ;
const SColorf col ( v [ j ] . Color ) ;
2020-04-27 22:52:21 +02:00
writeColor ( file , col ) ;
const core : : vector2df uv1 = v [ j ] . TCoords ;
writeVector2 ( file , uv1 ) ;
if ( texcoordsCount = = 2 )
2019-12-12 17:32:41 +01:00
{
2020-04-27 22:52:21 +02:00
writeVector2 ( file , core : : vector2df ( 0.f , 0.f ) ) ;
2019-12-12 17:32:41 +01:00
}
}
break ;
case EVT_2TCOORDS :
{
S3DVertex2TCoords * v = ( S3DVertex2TCoords * ) mb - > getVertices ( ) ;
const SColorf col ( v [ j ] . Color ) ;
2020-04-27 22:52:21 +02:00
writeColor ( file , col ) ;
const core : : vector2df uv1 = v [ j ] . TCoords ;
writeVector2 ( file , uv1 ) ;
const core : : vector2df uv2 = v [ j ] . TCoords ;
writeVector2 ( file , uv2 ) ;
2019-12-12 17:32:41 +01:00
}
break ;
case EVT_TANGENTS :
{
S3DVertexTangents * v = ( S3DVertexTangents * ) mb - > getVertices ( ) ;
const SColorf col ( v [ j ] . Color ) ;
2020-04-27 22:52:21 +02:00
writeColor ( file , col ) ;
const core : : vector2df uv1 = v [ j ] . TCoords ;
writeVector2 ( file , uv1 ) ;
if ( texcoordsCount = = 2 )
2019-12-12 17:32:41 +01:00
{
2020-04-27 22:52:21 +02:00
writeVector2 ( file , core : : vector2df ( 0.f , 0.f ) ) ;
2019-12-12 17:32:41 +01:00
}
}
break ;
}
}
}
2020-04-27 22:52:21 +02:00
writeSizeFrom ( file , verticesSizeAdress + 4 , verticesSizeAdress ) ; // VERT chunk size
2019-12-12 17:32:41 +01:00
u32 currentMeshBufferIndex = 0 ;
// Tris
2020-04-27 22:52:21 +02:00
for ( u32 i = 0 ; i < numMeshBuffers ; i + + )
2019-12-12 17:32:41 +01:00
{
const IMeshBuffer * const mb = mesh - > getMeshBuffer ( i ) ;
2020-04-27 22:52:21 +02:00
file - > write ( " TRIS " , 4 ) ;
const u32 trisSizeAdress = file - > getPos ( ) ;
file - > write ( & trisSizeAdress , 4 ) ; // TRIS chunk size, updated later
2019-12-12 17:32:41 +01:00
2020-04-27 22:52:21 +02:00
file - > write ( & i , 4 ) ;
2019-12-12 17:32:41 +01:00
u32 numIndices = mb - > getIndexCount ( ) ;
2022-04-20 19:56:40 +02:00
if ( mb - > getIndexType ( ) = = video : : EIT_16BIT )
2019-12-12 17:32:41 +01:00
{
2022-04-20 19:56:40 +02:00
const u16 * const idx = mb - > getIndices ( ) ;
for ( u32 j = 0 ; j < numIndices ; j + = 3 )
{
u32 tmp = idx [ j ] + currentMeshBufferIndex ;
file - > write ( & tmp , sizeof ( u32 ) ) ;
2019-12-12 17:32:41 +01:00
2022-04-20 19:56:40 +02:00
tmp = idx [ j + 1 ] + currentMeshBufferIndex ;
file - > write ( & tmp , sizeof ( u32 ) ) ;
2019-12-12 17:32:41 +01:00
2022-04-20 19:56:40 +02:00
tmp = idx [ j + 2 ] + currentMeshBufferIndex ;
file - > write ( & tmp , sizeof ( u32 ) ) ;
}
}
else if ( mb - > getIndexType ( ) = = video : : EIT_32BIT )
{
const u32 * const idx = ( const u32 * ) mb - > getIndices ( ) ;
for ( u32 j = 0 ; j < numIndices ; j + = 3 )
{
u32 tmp = idx [ j ] + currentMeshBufferIndex ;
file - > write ( & tmp , sizeof ( u32 ) ) ;
tmp = idx [ j + 1 ] + currentMeshBufferIndex ;
file - > write ( & tmp , sizeof ( u32 ) ) ;
tmp = idx [ j + 2 ] + currentMeshBufferIndex ;
file - > write ( & tmp , sizeof ( u32 ) ) ;
}
}
2020-04-27 22:52:21 +02:00
writeSizeFrom ( file , trisSizeAdress + 4 , trisSizeAdress ) ; // TRIS chunk size
2019-12-12 17:32:41 +01:00
currentMeshBufferIndex + = mb - > getVertexCount ( ) ;
}
2020-04-27 22:52:21 +02:00
writeSizeFrom ( file , meshSizeAdress + 4 , meshSizeAdress ) ; // MESH chunk size
2019-12-12 17:32:41 +01:00
if ( ISkinnedMesh * skinnedMesh = getSkinned ( mesh ) )
{
// Write animation data
2020-04-27 22:52:21 +02:00
f32 animationSpeedMultiplier = 1.f ;
2019-12-12 17:32:41 +01:00
if ( ! skinnedMesh - > isStatic ( ) )
{
2020-04-27 22:52:21 +02:00
file - > write ( " ANIM " , 4 ) ;
2019-12-12 17:32:41 +01:00
const u32 animsize = 12 ;
2020-04-27 22:52:21 +02:00
file - > write ( & animsize , 4 ) ;
2019-12-12 17:32:41 +01:00
const u32 flags = 0 ;
2020-04-27 22:52:21 +02:00
f32 fps = skinnedMesh - > getAnimationSpeed ( ) ;
/* B3D file format use integer as keyframe, so there is some potential issues if the model use float as keyframe (Irrlicht use float) with a low animation FPS value
So we define a minimum animation FPS value to multiply the frame and FPS value if the FPS of the animation is too low to store the keyframe with integers */
const int minimumAnimationFPS = 60 ;
if ( fps < minimumAnimationFPS )
{
animationSpeedMultiplier = minimumAnimationFPS / fps ;
fps = minimumAnimationFPS ;
}
const u32 frames = static_cast < u32 > ( skinnedMesh - > getFrameCount ( ) * animationSpeedMultiplier ) ;
2019-12-12 17:32:41 +01:00
2020-04-27 22:52:21 +02:00
file - > write ( & flags , 4 ) ;
file - > write ( & frames , 4 ) ;
file - > write ( & fps , 4 ) ;
2019-12-12 17:32:41 +01:00
}
// Write joints
core : : array < ISkinnedMesh : : SJoint * > rootJoints = getRootJoints ( skinnedMesh ) ;
for ( u32 i = 0 ; i < rootJoints . size ( ) ; i + + )
{
2020-04-27 22:52:21 +02:00
writeJointChunk ( file , skinnedMesh , rootJoints [ i ] , animationSpeedMultiplier ) ;
2019-12-12 17:32:41 +01:00
}
}
2020-04-27 22:52:21 +02:00
writeSizeFrom ( file , nodeSizeAdress + 4 , nodeSizeAdress ) ; // Node chunk size
writeSizeFrom ( file , 8 , 4 ) ; // BB3D chunk size
2019-12-12 17:32:41 +01:00
return true ;
}
2020-04-27 22:52:21 +02:00
void CB3DMeshWriter : : writeJointChunk ( io : : IWriteFile * file , ISkinnedMesh * mesh , ISkinnedMesh : : SJoint * joint , f32 animationSpeedMultiplier )
2019-12-12 17:32:41 +01:00
{
// Node
2020-04-27 22:52:21 +02:00
file - > write ( " NODE " , 4 ) ;
const u32 nodeSizeAdress = file - > getPos ( ) ;
file - > write ( & nodeSizeAdress , 4 ) ;
2019-12-12 17:32:41 +01:00
core : : stringc name = joint - > Name ;
2020-04-27 22:52:21 +02:00
file - > write ( name . c_str ( ) , name . size ( ) ) ;
file - > write ( " " , 1 ) ;
2019-12-12 17:32:41 +01:00
// Position
2020-04-27 22:52:21 +02:00
const core : : vector3df pos = joint - > Animatedposition ;
writeVector3 ( file , pos ) ;
2019-12-12 17:32:41 +01:00
// Scale
core : : vector3df scale = joint - > Animatedscale ;
if ( scale = = core : : vector3df ( 0 , 0 , 0 ) )
scale = core : : vector3df ( 1 , 1 , 1 ) ;
2020-04-27 22:52:21 +02:00
writeVector3 ( file , scale ) ;
2019-12-12 17:32:41 +01:00
// Rotation
2020-04-27 22:52:21 +02:00
const core : : quaternion quat = joint - > Animatedrotation ;
writeQuaternion ( file , quat ) ;
2019-12-12 17:32:41 +01:00
// Bone
2020-04-27 22:52:21 +02:00
file - > write ( " BONE " , 4 ) ;
2019-12-12 17:32:41 +01:00
u32 bonesize = 8 * joint - > Weights . size ( ) ;
2020-04-27 22:52:21 +02:00
file - > write ( & bonesize , 4 ) ;
2019-12-12 17:32:41 +01:00
// Skinning ------------------
for ( u32 i = 0 ; i < joint - > Weights . size ( ) ; i + + )
{
const u32 vertexID = joint - > Weights [ i ] . vertex_id ;
const u32 bufferID = joint - > Weights [ i ] . buffer_id ;
const f32 weight = joint - > Weights [ i ] . strength ;
u32 b3dVertexID = vertexID ;
for ( u32 j = 0 ; j < bufferID ; j + + )
{
b3dVertexID + = mesh - > getMeshBuffer ( j ) - > getVertexCount ( ) ;
}
2020-04-27 22:52:21 +02:00
file - > write ( & b3dVertexID , 4 ) ;
file - > write ( & weight , 4 ) ;
2019-12-12 17:32:41 +01:00
}
// ---------------------------
2020-04-27 22:52:21 +02:00
f32 floatBuffer [ 5 ] ;
2019-12-12 17:32:41 +01:00
// Animation keys
if ( joint - > PositionKeys . size ( ) )
{
2020-04-27 22:52:21 +02:00
file - > write ( " KEYS " , 4 ) ;
2019-12-12 17:32:41 +01:00
u32 keysSize = 4 * joint - > PositionKeys . size ( ) * 4 ; // X, Y and Z pos + frame
keysSize + = 4 ; // Flag to define the type of the key
2020-04-27 22:52:21 +02:00
file - > write ( & keysSize , 4 ) ;
2019-12-12 17:32:41 +01:00
u32 flag = 1 ; // 1 = flag for position keys
2020-04-27 22:52:21 +02:00
file - > write ( & flag , 4 ) ;
2019-12-12 17:32:41 +01:00
for ( u32 i = 0 ; i < joint - > PositionKeys . size ( ) ; i + + )
{
2020-04-27 22:52:21 +02:00
const s32 frame = static_cast < s32 > ( joint - > PositionKeys [ i ] . frame * animationSpeedMultiplier ) ;
file - > write ( & frame , 4 ) ;
2019-12-12 17:32:41 +01:00
2020-04-27 22:52:21 +02:00
const core : : vector3df pos = joint - > PositionKeys [ i ] . position ;
pos . getAs3Values ( floatBuffer ) ;
file - > write ( floatBuffer , 12 ) ;
2019-12-12 17:32:41 +01:00
}
}
if ( joint - > RotationKeys . size ( ) )
{
2020-04-27 22:52:21 +02:00
file - > write ( " KEYS " , 4 ) ;
2019-12-12 17:32:41 +01:00
u32 keysSize = 4 * joint - > RotationKeys . size ( ) * 5 ; // W, X, Y and Z rot + frame
keysSize + = 4 ; // Flag
2020-04-27 22:52:21 +02:00
file - > write ( & keysSize , 4 ) ;
2019-12-12 17:32:41 +01:00
u32 flag = 4 ;
2020-04-27 22:52:21 +02:00
file - > write ( & flag , 4 ) ;
2019-12-12 17:32:41 +01:00
for ( u32 i = 0 ; i < joint - > RotationKeys . size ( ) ; i + + )
{
2020-04-27 22:52:21 +02:00
const s32 frame = static_cast < s32 > ( joint - > RotationKeys [ i ] . frame * animationSpeedMultiplier ) ;
2019-12-12 17:32:41 +01:00
const core : : quaternion rot = joint - > RotationKeys [ i ] . rotation ;
2020-04-27 22:52:21 +02:00
memcpy ( floatBuffer , & frame , 4 ) ;
floatBuffer [ 1 ] = rot . W ;
floatBuffer [ 2 ] = rot . X ;
floatBuffer [ 3 ] = rot . Y ;
floatBuffer [ 4 ] = rot . Z ;
file - > write ( floatBuffer , 20 ) ;
2019-12-12 17:32:41 +01:00
}
}
if ( joint - > ScaleKeys . size ( ) )
{
2020-04-27 22:52:21 +02:00
file - > write ( " KEYS " , 4 ) ;
2019-12-12 17:32:41 +01:00
u32 keysSize = 4 * joint - > ScaleKeys . size ( ) * 4 ; // X, Y and Z scale + frame
keysSize + = 4 ; // Flag
2020-04-27 22:52:21 +02:00
file - > write ( & keysSize , 4 ) ;
2019-12-12 17:32:41 +01:00
u32 flag = 2 ;
2020-04-27 22:52:21 +02:00
file - > write ( & flag , 4 ) ;
2019-12-12 17:32:41 +01:00
for ( u32 i = 0 ; i < joint - > ScaleKeys . size ( ) ; i + + )
{
2020-04-27 22:52:21 +02:00
const s32 frame = static_cast < s32 > ( joint - > ScaleKeys [ i ] . frame * animationSpeedMultiplier ) ;
file - > write ( & frame , 4 ) ;
2019-12-12 17:32:41 +01:00
2020-04-27 22:52:21 +02:00
const core : : vector3df scale = joint - > ScaleKeys [ i ] . scale ;
scale . getAs3Values ( floatBuffer ) ;
file - > write ( floatBuffer , 12 ) ;
2019-12-12 17:32:41 +01:00
}
}
for ( u32 i = 0 ; i < joint - > Children . size ( ) ; i + + )
{
2020-04-27 22:52:21 +02:00
writeJointChunk ( file , mesh , joint - > Children [ i ] , animationSpeedMultiplier ) ;
2019-12-12 17:32:41 +01:00
}
2020-04-27 22:52:21 +02:00
writeSizeFrom ( file , nodeSizeAdress + 4 , nodeSizeAdress ) ; // NODE chunk size
2019-12-12 17:32:41 +01:00
}
ISkinnedMesh * CB3DMeshWriter : : getSkinned ( IMesh * mesh )
{
if ( mesh - > getMeshType ( ) = = EAMT_SKINNED )
{
return static_cast < ISkinnedMesh * > ( mesh ) ;
}
return 0 ;
}
core : : array < ISkinnedMesh : : SJoint * > CB3DMeshWriter : : getRootJoints ( const ISkinnedMesh * mesh )
{
core : : array < ISkinnedMesh : : SJoint * > roots ;
core : : array < ISkinnedMesh : : SJoint * > allJoints = mesh - > getAllJoints ( ) ;
for ( u32 i = 0 ; i < allJoints . size ( ) ; i + + )
{
bool isRoot = true ;
ISkinnedMesh : : SJoint * testedJoint = allJoints [ i ] ;
for ( u32 j = 0 ; j < allJoints . size ( ) ; j + + )
{
ISkinnedMesh : : SJoint * testedJoint2 = allJoints [ j ] ;
for ( u32 k = 0 ; k < testedJoint2 - > Children . size ( ) ; k + + )
{
if ( testedJoint = = testedJoint2 - > Children [ k ] )
isRoot = false ;
}
}
if ( isRoot )
roots . push_back ( testedJoint ) ;
}
return roots ;
}
2022-05-15 15:43:32 +02:00
u32 CB3DMeshWriter : : getUVlayerCount ( const IMesh * mesh )
2019-12-12 17:32:41 +01:00
{
const u32 numBeshBuffers = mesh - > getMeshBufferCount ( ) ;
for ( u32 i = 0 ; i < numBeshBuffers ; i + + )
{
const IMeshBuffer * const mb = mesh - > getMeshBuffer ( i ) ;
if ( mb - > getVertexType ( ) = = EVT_2TCOORDS )
{
return 2 ;
}
}
return 1 ;
}
2020-04-27 22:52:21 +02:00
void CB3DMeshWriter : : writeVector2 ( io : : IWriteFile * file , const core : : vector2df & vec2 )
{
f32 buffer [ 2 ] = { vec2 . X , vec2 . Y } ;
file - > write ( buffer , 8 ) ;
}
void CB3DMeshWriter : : writeVector3 ( io : : IWriteFile * file , const core : : vector3df & vec3 )
{
f32 buffer [ 3 ] ;
vec3 . getAs3Values ( buffer ) ;
file - > write ( buffer , 12 ) ;
}
void CB3DMeshWriter : : writeQuaternion ( io : : IWriteFile * file , const core : : quaternion & quat )
{
f32 buffer [ 4 ] = { quat . W , quat . X , quat . Y , quat . Z } ;
file - > write ( buffer , 16 ) ;
}
void CB3DMeshWriter : : writeColor ( io : : IWriteFile * file , const video : : SColorf & color )
{
f32 buffer [ 4 ] = { color . r , color . g , color . b , color . a } ;
file - > write ( buffer , 16 ) ;
}
// Write the size from a given position to current position at a specific position in the file
void CB3DMeshWriter : : writeSizeFrom ( io : : IWriteFile * file , const u32 from , const u32 adressToWrite )
2019-12-12 17:32:41 +01:00
{
2020-04-27 22:52:21 +02:00
const long back = file - > getPos ( ) ;
file - > seek ( adressToWrite ) ;
const u32 sizeToWrite = back - from ;
file - > write ( & sizeToWrite , 4 ) ;
file - > seek ( back ) ;
2019-12-12 17:32:41 +01:00
}
} // end namespace
} // end namespace
# endif // _IRR_COMPILE_WITH_B3D_WRITER_