2007-05-20 11:03:49 -07:00
// Copyright (C) 2002-2007 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
2007-09-04 11:51:42 -07:00
# include "IrrCompileConfig.h"
# ifdef _IRR_COMPILE_WITH_3DS_LOADER_
2007-05-20 11:03:49 -07:00
# include "C3DSMeshFileLoader.h"
# include "os.h"
# include "SMeshBuffer.h"
# include "SAnimatedMesh.h"
# include "IReadFile.h"
2008-02-25 09:44:12 -08:00
# include "IVideoDriver.h"
# include "IMeshManipulator.h"
2007-05-20 11:03:49 -07:00
namespace irr
{
namespace scene
{
// Primary chunk
const u16 C3DS_MAIN3DS = 0x4D4D ;
// Main Chunks
const u16 C3DS_EDIT3DS = 0x3D3D ;
const u16 C3DS_KEYF3DS = 0xB000 ;
const u16 C3DS_VERSION = 0x0002 ;
const u16 C3DS_MESHVERSION = 0x3D3E ;
// sub chunks of C3DS_EDIT3DS
const u16 C3DS_EDIT_MATERIAL = 0xAFFF ;
const u16 C3DS_EDIT_OBJECT = 0x4000 ;
// sub chunks of C3DS_EDIT_MATERIAL
const u16 C3DS_MATNAME = 0xA000 ;
const u16 C3DS_MATAMBIENT = 0xA010 ;
const u16 C3DS_MATDIFFUSE = 0xA020 ;
const u16 C3DS_MATSPECULAR = 0xA030 ;
const u16 C3DS_MATSHININESS = 0xA040 ;
const u16 C3DS_MATSHIN2PCT = 0xA041 ;
const u16 C3DS_TRANSPARENCY = 0xA050 ;
2008-02-25 09:44:12 -08:00
const u16 C3DS_TRANSPARENCY_FALLOFF = 0xA052 ;
const u16 C3DS_REFL_BLUR = 0xA053 ;
2007-05-20 11:03:49 -07:00
const u16 C3DS_TWO_SIDE = 0xA081 ;
const u16 C3DS_WIRE = 0xA085 ;
const u16 C3DS_SHADING = 0xA100 ;
const u16 C3DS_MATTEXMAP = 0xA200 ;
const u16 C3DS_MATSPECMAP = 0xA204 ;
const u16 C3DS_MATOPACMAP = 0xA210 ;
const u16 C3DS_MATREFLMAP = 0xA220 ;
const u16 C3DS_MATBUMPMAP = 0xA230 ;
const u16 C3DS_MATMAPFILE = 0xA300 ;
const u16 C3DS_MAT_TEXTILING = 0xA351 ;
const u16 C3DS_MAT_USCALE = 0xA354 ;
const u16 C3DS_MAT_VSCALE = 0xA356 ;
const u16 C3DS_MAT_UOFFSET = 0xA358 ;
const u16 C3DS_MAT_VOFFSET = 0xA35A ;
// subs of C3DS_EDIT_OBJECT
const u16 C3DS_OBJTRIMESH = 0x4100 ;
// subs of C3DS_OBJTRIMESH
const u16 C3DS_TRIVERT = 0x4110 ;
const u16 C3DS_POINTFLAGARRAY = 0x4111 ;
const u16 C3DS_TRIFACE = 0x4120 ;
const u16 C3DS_TRIFACEMAT = 0x4130 ;
const u16 C3DS_TRIUV = 0x4140 ;
const u16 C3DS_TRISMOOTH = 0x4150 ;
const u16 C3DS_TRIMATRIX = 0x4160 ;
const u16 C3DS_MESHCOLOR = 0x4165 ;
const u16 C3DS_DIRECT_LIGHT = 0x4600 ;
const u16 C3DS_DL_INNER_RANGE = 0x4659 ;
const u16 C3DS_DL_OUTER_RANGE = 0x465A ;
const u16 C3DS_DL_MULTIPLIER = 0x465B ;
const u16 C3DS_CAMERA = 0x4700 ;
const u16 C3DS_CAM_SEE_CONE = 0x4710 ;
const u16 C3DS_CAM_RANGES = 0x4720 ;
// subs of C3DS_KEYF3DS
const u16 C3DS_KF_HDR = 0xB00A ;
const u16 C3DS_AMBIENT_TAG = 0xB001 ;
const u16 C3DS_OBJECT_TAG = 0xB002 ;
const u16 C3DS_CAMERA_TAG = 0xB003 ;
const u16 C3DS_TARGET_TAG = 0xB004 ;
const u16 C3DS_LIGHTNODE_TAG = 0xB005 ;
const u16 C3DS_KF_SEG = 0xB008 ;
const u16 C3DS_KF_CURTIME = 0xB009 ;
const u16 C3DS_KF_NODE_HDR = 0xB010 ;
const u16 C3DS_PIVOTPOINT = 0xB013 ;
const u16 C3DS_BOUNDBOX = 0xB014 ;
const u16 C3DS_POS_TRACK_TAG = 0xB020 ;
const u16 C3DS_ROT_TRACK_TAG = 0xB021 ;
const u16 C3DS_SCL_TRACK_TAG = 0xB022 ;
const u16 C3DS_NODE_ID = 0xB030 ;
// different color chunk types
const u16 C3DS_COL_RGB = 0x0010 ;
const u16 C3DS_COL_TRU = 0x0011 ;
const u16 C3DS_COL_LIN_24 = 0x0012 ;
const u16 C3DS_COL_LIN_F = 0x0013 ;
// percentage chunk types
const u16 C3DS_PERCENTAGE_I = 0x0030 ;
const u16 C3DS_PERCENTAGE_F = 0x0031 ;
//! Constructor
2008-02-25 09:44:12 -08:00
C3DSMeshFileLoader : : C3DSMeshFileLoader ( ISceneManager * smgr , io : : IFileSystem * fs )
: SceneManager ( smgr ) , FileSystem ( fs ) , Vertices ( 0 ) , Indices ( 0 ) , SmoothingGroups ( 0 ) , TCoords ( 0 ) ,
CountVertices ( 0 ) , CountFaces ( 0 ) , CountTCoords ( 0 ) , Mesh ( 0 )
2007-05-20 11:03:49 -07:00
{
TransformationMatrix . makeIdentity ( ) ;
if ( FileSystem )
FileSystem - > grab ( ) ;
}
//! destructor
C3DSMeshFileLoader : : ~ C3DSMeshFileLoader ( )
{
2007-08-28 15:37:57 -07:00
cleanUp ( ) ;
2007-05-20 11:03:49 -07:00
if ( FileSystem )
FileSystem - > drop ( ) ;
if ( Mesh )
Mesh - > drop ( ) ;
}
//! returns true if the file maybe is able to be loaded by this class
//! based on the file extension (e.g. ".bsp")
2007-09-16 16:41:55 -07:00
bool C3DSMeshFileLoader : : isALoadableFileExtension ( const c8 * filename ) const
2007-05-20 11:03:49 -07:00
{
return strstr ( filename , " .3ds " ) ! = 0 ;
}
//! creates/loads an animated mesh from the file.
//! \return Pointer to the created mesh. Returns 0 if loading failed.
//! If you no longer need the mesh, you should call IAnimatedMesh::drop().
2007-09-06 23:11:47 -07:00
//! See IReferenceCounted::drop() for more information.
2007-05-20 11:03:49 -07:00
IAnimatedMesh * C3DSMeshFileLoader : : createMesh ( io : : IReadFile * file )
{
ChunkData data ;
readChunkData ( file , data ) ;
if ( data . header . id ! = C3DS_MAIN3DS )
return 0 ;
CurrentMaterial . clear ( ) ;
Materials . clear ( ) ;
MeshBufferNames . clear ( ) ;
cleanUp ( ) ;
if ( Mesh )
Mesh - > drop ( ) ;
Mesh = new SMesh ( ) ;
if ( readChunk ( file , & data ) )
{
// success
SAnimatedMesh * am = new SAnimatedMesh ( ) ;
am - > Type = EAMT_3DS ;
for ( u32 i = 0 ; i < Mesh - > getMeshBufferCount ( ) ; + + i )
{
SMeshBuffer * mb = ( ( SMeshBuffer * ) Mesh - > getMeshBuffer ( i ) ) ;
// drop empty buffers
if ( mb - > getIndexCount ( ) = = 0 | | mb - > getVertexCount ( ) = = 0 )
{
Mesh - > MeshBuffers . erase ( i - - ) ;
mb - > drop ( ) ;
}
else
2008-02-25 09:44:12 -08:00
{
2007-05-20 11:03:49 -07:00
mb - > recalculateBoundingBox ( ) ;
2008-02-25 09:44:12 -08:00
if ( mb - > Material . MaterialType = = video : : EMT_PARALLAX_MAP_SOLID )
{
SMesh tmp ;
tmp . addMeshBuffer ( mb ) ;
IMesh * tangentMesh = SceneManager - > getMeshManipulator ( ) - > createMeshWithTangents ( & tmp ) ;
mb - > drop ( ) ;
Mesh - > MeshBuffers [ i ] = tangentMesh - > getMeshBuffer ( 0 ) ;
}
}
2007-05-20 11:03:49 -07:00
}
Mesh - > recalculateBoundingBox ( ) ;
am - > addMesh ( Mesh ) ;
am - > recalculateBoundingBox ( ) ;
Mesh - > drop ( ) ;
Mesh = 0 ;
return am ;
}
Mesh - > drop ( ) ;
Mesh = 0 ;
return 0 ;
}
bool C3DSMeshFileLoader : : readPercentageChunk ( io : : IReadFile * file ,
ChunkData * chunk , f32 & percentage )
{
ChunkData data ;
readChunkData ( file , data ) ;
short intpercentage ;
float fpercentage ;
switch ( data . header . id )
{
case C3DS_PERCENTAGE_I :
{
// read short
file - > read ( & intpercentage , 2 ) ;
# ifdef __BIG_ENDIAN__
intpercentage = os : : Byteswap : : byteswap ( intpercentage ) ;
# endif
percentage = intpercentage / 100.0f ;
data . read + = 2 ;
}
break ;
case C3DS_PERCENTAGE_F :
{
// read float
file - > read ( & fpercentage , sizeof ( float ) ) ;
data . read + = sizeof ( float ) ;
# ifdef __BIG_ENDIAN__
percentage = os : : Byteswap : : byteswap ( fpercentage ) ;
# else
percentage = ( f32 ) fpercentage ;
# endif
}
break ;
default :
{
// unknown percentage chunk
os : : Printer : : log ( " Unknown percentage chunk in 3Ds file. " , ELL_WARNING ) ;
file - > seek ( data . header . length - data . read , true ) ;
data . read + = data . header . length - data . read ;
}
}
chunk - > read + = data . read ;
return true ;
}
bool C3DSMeshFileLoader : : readColorChunk ( io : : IReadFile * file , ChunkData * chunk ,
video : : SColor & out )
{
ChunkData data ;
readChunkData ( file , data ) ;
u8 c [ 3 ] ;
f32 cf [ 3 ] ;
switch ( data . header . id )
{
case C3DS_COL_TRU :
case C3DS_COL_LIN_24 :
{
// read 8 bit data
file - > read ( c , sizeof ( c ) ) ;
out . set ( 255 , c [ 0 ] , c [ 1 ] , c [ 2 ] ) ;
data . read + = sizeof ( c ) ;
}
break ;
case C3DS_COL_RGB :
case C3DS_COL_LIN_F :
{
// read float data
file - > read ( cf , sizeof ( cf ) ) ;
# ifdef __BIG_ENDIAN__
cf [ 0 ] = os : : Byteswap : : byteswap ( cf [ 0 ] ) ;
cf [ 1 ] = os : : Byteswap : : byteswap ( cf [ 1 ] ) ;
cf [ 2 ] = os : : Byteswap : : byteswap ( cf [ 2 ] ) ;
# endif
out . set ( 255 , ( s32 ) ( cf [ 0 ] * 255.0f ) , ( s32 ) ( cf [ 1 ] * 255.0f ) , ( s32 ) ( cf [ 2 ] * 255.0f ) ) ;
data . read + = sizeof ( cf ) ;
}
break ;
default :
{
// unknown color chunk size
os : : Printer : : log ( " Unknown size of color chunk in 3Ds file. " , ELL_WARNING ) ;
file - > seek ( data . header . length - data . read , true ) ;
data . read + = data . header . length - data . read ;
}
}
chunk - > read + = data . read ;
return true ;
}
bool C3DSMeshFileLoader : : readMaterialChunk ( io : : IReadFile * file , ChunkData * parent )
{
u16 matSection = 0 ;
while ( parent - > read < parent - > header . length )
{
ChunkData data ;
readChunkData ( file , data ) ;
switch ( data . header . id )
{
case C3DS_MATNAME :
{
c8 * c = new c8 [ data . header . length - data . read ] ;
file - > read ( c , data . header . length - data . read ) ;
if ( strlen ( c ) )
CurrentMaterial . Name = c ;
data . read + = data . header . length - data . read ;
delete [ ] c ;
}
break ;
case C3DS_MATAMBIENT :
readColorChunk ( file , & data , CurrentMaterial . Material . AmbientColor ) ;
break ;
case C3DS_MATDIFFUSE :
readColorChunk ( file , & data , CurrentMaterial . Material . DiffuseColor ) ;
break ;
case C3DS_MATSPECULAR :
readColorChunk ( file , & data , CurrentMaterial . Material . SpecularColor ) ;
break ;
case C3DS_MATSHININESS :
readPercentageChunk ( file , & data , CurrentMaterial . Material . Shininess ) ;
break ;
case C3DS_TRANSPARENCY :
{
f32 percentage ;
readPercentageChunk ( file , & data , percentage ) ;
if ( percentage > 0.0f )
{
CurrentMaterial . Material . MaterialTypeParam = percentage ;
CurrentMaterial . Material . MaterialType = video : : EMT_TRANSPARENT_VERTEX_ALPHA ;
}
else
{
CurrentMaterial . Material . MaterialType = video : : EMT_SOLID ;
}
}
break ;
case C3DS_WIRE :
CurrentMaterial . Material . Wireframe = true ;
break ;
case C3DS_TWO_SIDE :
CurrentMaterial . Material . BackfaceCulling = false ;
break ;
case C3DS_SHADING :
{
s16 flags ;
file - > read ( & flags , 2 ) ;
# ifdef __BIG_ENDIAN__
flags = os : : Byteswap : : byteswap ( flags ) ;
# endif
switch ( flags )
{
case 0 :
CurrentMaterial . Material . Wireframe = true ;
break ;
case 1 :
CurrentMaterial . Material . Wireframe = false ;
CurrentMaterial . Material . GouraudShading = false ;
break ;
case 2 :
CurrentMaterial . Material . Wireframe = false ;
CurrentMaterial . Material . GouraudShading = true ;
break ;
default :
// phong and metal missing
break ;
}
data . read + = data . header . length - data . read ;
}
break ;
case C3DS_MATTEXMAP :
case C3DS_MATSPECMAP :
case C3DS_MATOPACMAP :
case C3DS_MATREFLMAP :
case C3DS_MATBUMPMAP :
{
matSection = data . header . id ;
2008-02-25 09:44:12 -08:00
# if 1 // Should contain a percentage chunk, but does not work with the meshes
switch ( matSection )
{
case C3DS_MATTEXMAP :
readPercentageChunk ( file , & data , CurrentMaterial . Strength [ 0 ] ) ;
break ;
case C3DS_MATSPECMAP :
readPercentageChunk ( file , & data , CurrentMaterial . Strength [ 1 ] ) ;
break ;
case C3DS_MATOPACMAP :
readPercentageChunk ( file , & data , CurrentMaterial . Strength [ 2 ] ) ;
break ;
case C3DS_MATBUMPMAP :
readPercentageChunk ( file , & data , CurrentMaterial . Strength [ 4 ] ) ;
break ;
}
2007-05-20 11:03:49 -07:00
# endif
}
break ;
case C3DS_MATMAPFILE :
{
// read texture file name
c8 * c = new c8 [ data . header . length - data . read ] ;
file - > read ( c , data . header . length - data . read ) ;
2007-12-08 05:11:39 -08:00
switch ( matSection )
{
case C3DS_MATTEXMAP :
2007-05-20 11:03:49 -07:00
CurrentMaterial . Filename [ 0 ] = c ;
2007-12-08 05:11:39 -08:00
break ;
case C3DS_MATSPECMAP :
2007-05-20 11:03:49 -07:00
CurrentMaterial . Filename [ 1 ] = c ;
2007-12-08 05:11:39 -08:00
break ;
case C3DS_MATOPACMAP :
2007-05-20 11:03:49 -07:00
CurrentMaterial . Filename [ 2 ] = c ;
2007-12-08 05:11:39 -08:00
break ;
case C3DS_MATREFLMAP :
2007-05-20 11:03:49 -07:00
CurrentMaterial . Filename [ 3 ] = c ;
2007-12-08 05:11:39 -08:00
break ;
case C3DS_MATBUMPMAP :
2007-05-20 11:03:49 -07:00
CurrentMaterial . Filename [ 4 ] = c ;
2007-12-08 05:11:39 -08:00
break ;
}
2007-05-20 11:03:49 -07:00
data . read + = data . header . length - data . read ;
delete [ ] c ;
}
break ;
case C3DS_MAT_TEXTILING :
{
s16 flags ;
file - > read ( & flags , 2 ) ;
# ifdef __BIG_ENDIAN__
flags = os : : Byteswap : : byteswap ( flags ) ;
# endif
data . read + = 2 ;
}
break ;
case C3DS_MAT_USCALE :
case C3DS_MAT_VSCALE :
case C3DS_MAT_UOFFSET :
case C3DS_MAT_VOFFSET :
{
f32 value ;
file - > read ( & value , 4 ) ;
# ifdef __BIG_ENDIAN__
value = os : : Byteswap : : byteswap ( value ) ;
# endif
2007-12-08 05:11:39 -08:00
u32 i = 0 ;
if ( matSection ! = C3DS_MATTEXMAP )
i = 1 ;
u32 j = 0 , k = 0 ;
if ( data . header . id = = C3DS_MAT_VSCALE )
{
j = 1 ;
k = 1 ;
}
else if ( data . header . id = = C3DS_MAT_UOFFSET )
{
j = 2 ;
k = 0 ;
}
else if ( data . header . id = = C3DS_MAT_VOFFSET )
{
j = 2 ;
k = 1 ;
}
CurrentMaterial . Material . getTextureMatrix ( i ) ( j , k ) = value ;
2007-05-20 11:03:49 -07:00
data . read + = 4 ;
}
break ;
default :
// ignore chunk
file - > seek ( data . header . length - data . read , true ) ;
data . read + = data . header . length - data . read ;
}
parent - > read + = data . read ;
}
Materials . push_back ( CurrentMaterial ) ;
CurrentMaterial . clear ( ) ;
return true ;
}
bool C3DSMeshFileLoader : : readTrackChunk ( io : : IReadFile * file , ChunkData & data ,
IMeshBuffer * mb , const core : : vector3df & pivot )
{
u16 flags ;
u32 flags2 ;
// Track flags
file - > read ( & flags , 2 ) ;
# ifdef __BIG_ENDIAN__
flags = os : : Byteswap : : byteswap ( flags ) ;
# endif
file - > read ( & flags2 , 4 ) ;
# ifdef __BIG_ENDIAN__
flags2 = os : : Byteswap : : byteswap ( flags2 ) ;
# endif
file - > read ( & flags2 , 4 ) ;
# ifdef __BIG_ENDIAN__
flags2 = os : : Byteswap : : byteswap ( flags2 ) ;
# endif
// Num keys
file - > read ( & flags2 , 4 ) ;
# ifdef __BIG_ENDIAN__
flags2 = os : : Byteswap : : byteswap ( flags2 ) ;
# endif
file - > read ( & flags2 , 4 ) ;
# ifdef __BIG_ENDIAN__
flags2 = os : : Byteswap : : byteswap ( flags2 ) ;
# endif
// TCB flags
file - > read ( & flags , 2 ) ;
# ifdef __BIG_ENDIAN__
flags = os : : Byteswap : : byteswap ( flags ) ;
# endif
data . read + = 20 ;
f32 angle = 0.0f ;
if ( data . header . id = = C3DS_ROT_TRACK_TAG )
{
// Angle
file - > read ( & angle , sizeof ( f32 ) ) ;
# ifdef __BIG_ENDIAN__
angle = os : : Byteswap : : byteswap ( angle ) ;
# endif
data . read + = sizeof ( f32 ) ;
}
core : : vector3df vec ;
file - > read ( & vec . X , sizeof ( f32 ) ) ;
file - > read ( & vec . Y , sizeof ( f32 ) ) ;
file - > read ( & vec . Z , sizeof ( f32 ) ) ;
# ifdef __BIG_ENDIAN__
vec . X = os : : Byteswap : : byteswap ( vec . X ) ;
vec . Y = os : : Byteswap : : byteswap ( vec . X ) ;
vec . Z = os : : Byteswap : : byteswap ( vec . X ) ;
# endif
data . read + = 12 ;
vec - = pivot ;
// apply transformation to mesh buffer
if ( false ) //mb)
{
video : : S3DVertex * vertices = ( video : : S3DVertex * ) mb - > getVertices ( ) ;
if ( data . header . id = = C3DS_POS_TRACK_TAG )
{
for ( u32 i = 0 ; i < mb - > getVertexCount ( ) ; + + i )
vertices [ i ] . Pos + = vec ;
}
else if ( data . header . id = = C3DS_ROT_TRACK_TAG )
{
//TODO
}
else if ( data . header . id = = C3DS_SCL_TRACK_TAG )
{
//TODO
}
}
// skip further frames
file - > seek ( data . header . length - data . read , true ) ;
data . read + = data . header . length - data . read ;
return true ;
}
bool C3DSMeshFileLoader : : readFrameChunk ( io : : IReadFile * file , ChunkData * parent )
{
ChunkData data ;
//KF_HDR is always at the beginning
readChunkData ( file , data ) ;
if ( data . header . id ! = C3DS_KF_HDR )
return false ;
else
{
u16 flags ;
file - > read ( & flags , 2 ) ;
# ifdef __BIG_ENDIAN__
flags = os : : Byteswap : : byteswap ( flags ) ;
# endif
c8 * c = new c8 [ data . header . length - data . read - 4 ] ;
file - > read ( c , data . header . length - data . read - 4 ) ;
file - > read ( & flags , 2 ) ;
# ifdef __BIG_ENDIAN__
flags = os : : Byteswap : : byteswap ( flags ) ;
# endif
data . read + = data . header . length - data . read ;
parent - > read + = data . read ;
delete [ ] c ;
}
IMeshBuffer * mb = 0 ;
core : : vector3df pivot , bboxCenter ;
while ( parent - > read < parent - > header . length )
{
readChunkData ( file , data ) ;
switch ( data . header . id )
{
case C3DS_OBJECT_TAG :
{
mb = 0 ;
pivot . set ( 0.0f , 0.0f , 0.0f ) ;
}
break ;
case C3DS_KF_SEG :
{
u32 flags ;
file - > read ( & flags , 4 ) ;
# ifdef __BIG_ENDIAN__
flags = os : : Byteswap : : byteswap ( flags ) ;
# endif
file - > read ( & flags , 4 ) ;
# ifdef __BIG_ENDIAN__
flags = os : : Byteswap : : byteswap ( flags ) ;
# endif
data . read + = 8 ;
}
break ;
case C3DS_KF_NODE_HDR :
{
s16 flags ;
c8 * c = new c8 [ data . header . length - data . read - 6 ] ;
file - > read ( c , data . header . length - data . read - 6 ) ;
// search mesh buffer to apply these transformations to
for ( u32 i = 0 ; i < MeshBufferNames . size ( ) ; + + i )
{
if ( MeshBufferNames [ i ] = = c )
{
mb = Mesh - > getMeshBuffer ( i ) ;
break ;
}
}
file - > read ( & flags , 2 ) ;
# ifdef __BIG_ENDIAN__
flags = os : : Byteswap : : byteswap ( flags ) ;
# endif
file - > read ( & flags , 2 ) ;
# ifdef __BIG_ENDIAN__
flags = os : : Byteswap : : byteswap ( flags ) ;
# endif
file - > read ( & flags , 2 ) ;
# ifdef __BIG_ENDIAN__
flags = os : : Byteswap : : byteswap ( flags ) ;
# endif
data . read + = data . header . length - data . read ;
delete [ ] c ;
}
break ;
case C3DS_KF_CURTIME :
{
u32 flags ;
file - > read ( & flags , 4 ) ;
# ifdef __BIG_ENDIAN__
flags = os : : Byteswap : : byteswap ( flags ) ;
# endif
data . read + = 4 ;
}
break ;
case C3DS_NODE_ID :
{
u16 flags ;
file - > read ( & flags , 2 ) ;
# ifdef __BIG_ENDIAN__
flags = os : : Byteswap : : byteswap ( flags ) ;
# endif
data . read + = 2 ;
}
break ;
case C3DS_PIVOTPOINT :
{
file - > read ( & pivot . X , sizeof ( f32 ) ) ;
file - > read ( & pivot . Y , sizeof ( f32 ) ) ;
file - > read ( & pivot . Z , sizeof ( f32 ) ) ;
# ifdef __BIG_ENDIAN__
pivot . X = os : : Byteswap : : byteswap ( pivot . X ) ;
pivot . Y = os : : Byteswap : : byteswap ( pivot . Y ) ;
pivot . Z = os : : Byteswap : : byteswap ( pivot . Z ) ;
# endif
data . read + = 12 ;
}
break ;
case C3DS_BOUNDBOX :
{
core : : aabbox3df bbox ;
// abuse bboxCenter as temporary variable
file - > read ( & bboxCenter . X , sizeof ( f32 ) ) ;
file - > read ( & bboxCenter . Y , sizeof ( f32 ) ) ;
file - > read ( & bboxCenter . Z , sizeof ( f32 ) ) ;
# ifdef __BIG_ENDIAN__
bboxCenter . X = os : : Byteswap : : byteswap ( bboxCenter . X ) ;
bboxCenter . Y = os : : Byteswap : : byteswap ( bboxCenter . Y ) ;
bboxCenter . Z = os : : Byteswap : : byteswap ( bboxCenter . Z ) ;
# endif
bbox . reset ( bboxCenter ) ;
file - > read ( & bboxCenter . X , sizeof ( f32 ) ) ;
file - > read ( & bboxCenter . Y , sizeof ( f32 ) ) ;
file - > read ( & bboxCenter . Z , sizeof ( f32 ) ) ;
# ifdef __BIG_ENDIAN__
bboxCenter . X = os : : Byteswap : : byteswap ( bboxCenter . X ) ;
bboxCenter . Y = os : : Byteswap : : byteswap ( bboxCenter . Y ) ;
bboxCenter . Z = os : : Byteswap : : byteswap ( bboxCenter . Z ) ;
# endif
bbox . addInternalPoint ( bboxCenter ) ;
bboxCenter = bbox . getCenter ( ) ;
data . read + = 24 ;
}
break ;
case C3DS_POS_TRACK_TAG :
case C3DS_ROT_TRACK_TAG :
case C3DS_SCL_TRACK_TAG :
readTrackChunk ( file , data , mb , bboxCenter - pivot ) ;
break ;
default :
// ignore chunk
file - > seek ( data . header . length - data . read , true ) ;
data . read + = data . header . length - data . read ;
}
parent - > read + = data . read ;
data . read = 0 ;
}
return true ;
}
bool C3DSMeshFileLoader : : readChunk ( io : : IReadFile * file , ChunkData * parent )
{
while ( parent - > read < parent - > header . length )
{
ChunkData data ;
readChunkData ( file , data ) ;
switch ( data . header . id )
{
case C3DS_VERSION :
{
u16 version ;
file - > read ( & version , sizeof ( u16 ) ) ;
# ifdef __BIG_ENDIAN__
version = os : : Byteswap : : byteswap ( version ) ;
# endif
file - > seek ( data . header . length - data . read - 2 , true ) ;
data . read + = data . header . length - data . read ;
if ( version ! = 0x03 )
os : : Printer : : log ( " 3ds file version is other than 3. " , ELL_ERROR ) ;
}
break ;
case C3DS_EDIT_MATERIAL :
readMaterialChunk ( file , & data ) ;
break ;
case C3DS_KEYF3DS :
readFrameChunk ( file , & data ) ;
break ;
case C3DS_EDIT3DS :
break ;
case C3DS_MESHVERSION :
case 0x01 :
{
u32 version ;
file - > read ( & version , sizeof ( u32 ) ) ;
# ifdef __BIG_ENDIAN__
version = os : : Byteswap : : byteswap ( version ) ;
# endif
data . read + = sizeof ( u32 ) ;
}
break ;
case C3DS_EDIT_OBJECT :
{
core : : stringc name ;
readString ( file , data , name ) ;
readObjectChunk ( file , & data ) ;
composeObject ( file , name ) ;
}
break ;
default :
// ignore chunk
file - > seek ( data . header . length - data . read , true ) ;
data . read + = data . header . length - data . read ;
}
parent - > read + = data . read ;
}
return true ;
}
bool C3DSMeshFileLoader : : readObjectChunk ( io : : IReadFile * file , ChunkData * parent )
{
while ( parent - > read < parent - > header . length )
{
ChunkData data ;
readChunkData ( file , data ) ;
switch ( data . header . id )
{
case C3DS_OBJTRIMESH :
readObjectChunk ( file , & data ) ;
break ;
case C3DS_TRIVERT :
readVertices ( file , data ) ;
break ;
case C3DS_POINTFLAGARRAY :
{
u16 numVertex , flags ;
file - > read ( & numVertex , sizeof ( u16 ) ) ;
# ifdef __BIG_ENDIAN__
numVertex = os : : Byteswap : : byteswap ( numVertex ) ;
# endif
for ( u16 i = 0 ; i < numVertex ; + + i )
{
file - > read ( & flags , sizeof ( u16 ) ) ;
# ifdef __BIG_ENDIAN__
flags = os : : Byteswap : : byteswap ( flags ) ;
# endif
}
data . read + = ( numVertex + 1 ) * sizeof ( u16 ) ;
}
break ;
case C3DS_TRIFACE :
readIndices ( file , data ) ;
readObjectChunk ( file , & data ) ; // read smooth and material groups
break ;
case C3DS_TRIFACEMAT :
readMaterialGroup ( file , data ) ;
break ;
case C3DS_TRIUV : // getting texture coordinates
readTextureCoords ( file , data ) ;
break ;
case C3DS_TRIMATRIX :
{
f32 mat [ 4 ] [ 3 ] ;
file - > read ( & mat , 12 * sizeof ( f32 ) ) ;
TransformationMatrix . makeIdentity ( ) ;
for ( int i = 0 ; i < 4 ; + + i )
{
for ( int j = 0 ; j < 3 ; + + j )
{
# ifdef __BIG_ENDIAN__
TransformationMatrix ( i , j ) = os : : Byteswap : : byteswap ( mat [ i ] [ j ] ) ;
# else
TransformationMatrix ( i , j ) = mat [ i ] [ j ] ;
# endif
}
}
data . read + = 12 * sizeof ( f32 ) ;
}
break ;
case C3DS_MESHCOLOR :
{
u8 flag ;
file - > read ( & flag , sizeof ( u8 ) ) ;
+ + data . read ;
}
break ;
case C3DS_TRISMOOTH : // TODO
{
2007-08-28 15:37:57 -07:00
SmoothingGroups = new u32 [ CountFaces ] ;
2007-08-29 14:15:35 -07:00
file - > read ( SmoothingGroups , CountFaces * sizeof ( u32 ) ) ;
2007-05-20 11:03:49 -07:00
# ifdef __BIG_ENDIAN__
for ( u16 i = 0 ; i < CountFaces ; + + i )
2007-08-29 14:15:35 -07:00
SmoothingGroups [ i ] = os : : Byteswap : : byteswap ( SmoothingGroups [ i ] ) ;
2007-05-20 11:03:49 -07:00
# endif
data . read + = CountFaces * sizeof ( u32 ) ;
}
break ;
default :
// ignore chunk
file - > seek ( data . header . length - data . read , true ) ;
data . read + = data . header . length - data . read ;
}
parent - > read + = data . read ;
}
return true ;
}
void C3DSMeshFileLoader : : composeObject ( io : : IReadFile * file , const core : : stringc & name )
{
if ( Mesh - > getMeshBufferCount ( ) ! = Materials . size ( ) )
loadMaterials ( file ) ;
if ( MaterialGroups . empty ( ) )
{
// no material group, so add all
SMaterialGroup group ;
group . faceCount = CountFaces ;
2007-08-15 08:55:20 -07:00
group . faces = new u16 [ group . faceCount ] ;
for ( u32 i = 0 ; i < group . faceCount ; + + i )
2007-05-20 11:03:49 -07:00
group . faces [ i ] = i ;
MaterialGroups . push_back ( group ) ;
// if we've got no material, add one without a texture
if ( Materials . empty ( ) )
{
SCurrentMaterial m ;
Materials . push_back ( m ) ;
SMeshBuffer * mb = new scene : : SMeshBuffer ( ) ;
Mesh - > addMeshBuffer ( mb ) ;
2007-06-02 04:09:32 -07:00
mb - > getMaterial ( ) = Materials [ 0 ] . Material ;
2007-05-20 11:03:49 -07:00
mb - > drop ( ) ;
// add an empty mesh buffer name
2007-12-08 05:11:39 -08:00
MeshBufferNames . push_back ( " " ) ;
2007-05-20 11:03:49 -07:00
}
}
for ( u32 i = 0 ; i < MaterialGroups . size ( ) ; + + i )
{
SMeshBuffer * mb = 0 ;
video : : SMaterial * mat = 0 ;
u32 mbPos ;
// -3 because we add three vertices at once
2008-02-25 09:44:12 -08:00
u32 maxPrimitives = core : : min_ ( SceneManager - > getVideoDriver ( ) - > getMaximalPrimitiveCount ( ) , ( u32 ) ( ( 1 < < 16 ) - 1 ) ) - 3 ; // currently hardcoded s16 max value for index pointers
2007-05-20 11:03:49 -07:00
// find mesh buffer for this group
for ( mbPos = 0 ; mbPos < Materials . size ( ) ; + + mbPos )
{
if ( MaterialGroups [ i ] . MaterialName = = Materials [ mbPos ] . Name )
{
mb = ( SMeshBuffer * ) Mesh - > getMeshBuffer ( mbPos ) ;
mat = & Materials [ mbPos ] . Material ;
MeshBufferNames [ mbPos ] = name ;
break ;
}
}
if ( mb ! = 0 )
{
// add geometry to the buffer.
video : : S3DVertex vtx ;
core : : vector3df vec ;
vtx . Color = mat - > DiffuseColor ;
if ( mat - > MaterialType = = video : : EMT_TRANSPARENT_VERTEX_ALPHA )
{
vtx . Color . setAlpha ( ( int ) ( 255.0f * mat - > MaterialTypeParam ) ) ;
}
vtx . Normal . set ( 0 , 0 , 0 ) ;
for ( s32 f = 0 ; f < MaterialGroups [ i ] . faceCount ; + + f )
{
u32 vtxCount = mb - > Vertices . size ( ) ;
if ( vtxCount > maxPrimitives )
2007-06-27 11:11:23 -07:00
{
2007-05-20 11:03:49 -07:00
IMeshBuffer * tmp = mb ;
2007-06-27 11:11:23 -07:00
mb = new SMeshBuffer ( ) ;
Mesh - > addMeshBuffer ( mb ) ;
mb - > drop ( ) ;
Mesh - > MeshBuffers [ mbPos ] = Mesh - > MeshBuffers . getLast ( ) ;
Mesh - > MeshBuffers [ Mesh - > MeshBuffers . size ( ) - 1 ] = tmp ;
2007-12-23 09:04:40 -08:00
mb - > getMaterial ( ) = tmp - > getMaterial ( ) ;
2007-05-20 11:03:49 -07:00
vtxCount = 0 ;
}
for ( s32 v = 0 ; v < 3 ; + + v )
{
s32 idx = Indices [ MaterialGroups [ i ] . faces [ f ] * 4 + v ] ;
if ( CountVertices > idx )
{
vtx . Pos . X = Vertices [ idx * 3 + 0 ] ;
vtx . Pos . Z = Vertices [ idx * 3 + 1 ] ;
vtx . Pos . Y = Vertices [ idx * 3 + 2 ] ;
// TransformationMatrix.transformVect(vtx.Pos);
}
if ( CountTCoords > idx )
{
vtx . TCoords . X = TCoords [ idx * 2 + 0 ] ;
vtx . TCoords . Y = 1.0f - TCoords [ idx * 2 + 1 ] ;
}
mb - > Vertices . push_back ( vtx ) ;
}
// compute normal
core : : plane3d < f32 > pl ( mb - > Vertices [ vtxCount ] . Pos , mb - > Vertices [ vtxCount + 2 ] . Pos ,
mb - > Vertices [ vtxCount + 1 ] . Pos ) ;
mb - > Vertices [ vtxCount ] . Normal = pl . Normal ;
mb - > Vertices [ vtxCount + 1 ] . Normal = pl . Normal ;
mb - > Vertices [ vtxCount + 2 ] . Normal = pl . Normal ;
// add indices
mb - > Indices . push_back ( vtxCount ) ;
mb - > Indices . push_back ( vtxCount + 2 ) ;
mb - > Indices . push_back ( vtxCount + 1 ) ;
}
}
else
os : : Printer : : log ( " Found no matching material for Group in 3ds file. " , ELL_WARNING ) ;
}
cleanUp ( ) ;
}
core : : stringc C3DSMeshFileLoader : : getTextureFileName ( const core : : stringc & texture ,
core : : stringc & model )
{
s32 idx = - 1 ;
idx = model . findLast ( ' / ' ) ;
if ( idx = = - 1 )
idx = model . findLast ( ' \\ ' ) ;
if ( idx = = - 1 )
return core : : stringc ( ) ;
core : : stringc p = model . subString ( 0 , idx + 1 ) ;
p . append ( texture ) ;
return p ;
}
void C3DSMeshFileLoader : : loadMaterials ( io : : IReadFile * file )
{
// create a mesh buffer for every material
core : : stringc modelFilename = file - > getFileName ( ) ;
if ( Materials . empty ( ) )
os : : Printer : : log ( " No materials found in 3ds file. " , ELL_INFORMATION ) ;
MeshBufferNames . reallocate ( Materials . size ( ) ) ;
for ( u32 i = 0 ; i < Materials . size ( ) ; + + i )
{
MeshBufferNames . push_back ( " " ) ;
SMeshBuffer * m = new scene : : SMeshBuffer ( ) ;
Mesh - > addMeshBuffer ( m ) ;
2007-06-02 04:09:32 -07:00
m - > getMaterial ( ) = Materials [ i ] . Material ;
2007-05-20 11:03:49 -07:00
if ( Materials [ i ] . Filename [ 0 ] . size ( ) )
{
2008-02-25 09:44:12 -08:00
video : : ITexture * texture = SceneManager - > getVideoDriver ( ) - > getTexture ( Materials [ i ] . Filename [ 0 ] . c_str ( ) ) ;
2007-06-02 04:09:32 -07:00
if ( ! texture )
2007-05-20 11:03:49 -07:00
{
core : : stringc fname = getTextureFileName (
Materials [ i ] . Filename [ 0 ] , modelFilename ) ;
if ( fname . size ( ) )
2008-02-25 09:44:12 -08:00
texture = SceneManager - > getVideoDriver ( ) - > getTexture ( fname . c_str ( ) ) ;
2007-05-20 11:03:49 -07:00
}
2007-06-02 04:09:32 -07:00
if ( ! texture )
2007-05-20 11:03:49 -07:00
os : : Printer : : log ( " Could not load a texture for entry in 3ds file " ,
Materials [ i ] . Filename [ 0 ] . c_str ( ) , ELL_WARNING ) ;
2007-06-02 04:09:32 -07:00
else
2007-09-20 08:33:36 -07:00
m - > getMaterial ( ) . setTexture ( 0 , texture ) ;
2007-05-20 11:03:49 -07:00
}
if ( Materials [ i ] . Filename [ 2 ] . size ( ) )
{
2008-02-25 09:44:12 -08:00
video : : ITexture * texture = SceneManager - > getVideoDriver ( ) - > getTexture ( Materials [ i ] . Filename [ 2 ] . c_str ( ) ) ;
2007-06-02 04:09:32 -07:00
if ( ! texture )
2007-05-20 11:03:49 -07:00
{
core : : stringc fname = getTextureFileName (
Materials [ i ] . Filename [ 2 ] , modelFilename ) ;
if ( fname . size ( ) )
2008-02-25 09:44:12 -08:00
texture = SceneManager - > getVideoDriver ( ) - > getTexture ( fname . c_str ( ) ) ;
2007-05-20 11:03:49 -07:00
}
2007-06-02 04:09:32 -07:00
if ( ! texture )
2007-05-20 11:03:49 -07:00
{
os : : Printer : : log ( " Could not load a texture for entry in 3ds file " ,
Materials [ i ] . Filename [ 2 ] . c_str ( ) , ELL_WARNING ) ;
}
else
{
2007-09-20 08:33:36 -07:00
m - > getMaterial ( ) . setTexture ( 0 , texture ) ;
2007-06-02 04:09:32 -07:00
m - > getMaterial ( ) . MaterialType = video : : EMT_TRANSPARENT_ADD_COLOR ;
2007-05-20 11:03:49 -07:00
}
}
if ( Materials [ i ] . Filename [ 3 ] . size ( ) )
{
2008-02-25 09:44:12 -08:00
video : : ITexture * texture = SceneManager - > getVideoDriver ( ) - > getTexture ( Materials [ i ] . Filename [ 3 ] . c_str ( ) ) ;
2007-06-02 04:09:32 -07:00
if ( ! texture )
2007-05-20 11:03:49 -07:00
{
core : : stringc fname = getTextureFileName (
Materials [ i ] . Filename [ 3 ] , modelFilename ) ;
if ( fname . size ( ) )
2008-02-25 09:44:12 -08:00
texture = SceneManager - > getVideoDriver ( ) - > getTexture ( fname . c_str ( ) ) ;
2007-05-20 11:03:49 -07:00
}
2007-06-02 04:09:32 -07:00
if ( ! texture )
2007-05-20 11:03:49 -07:00
{
os : : Printer : : log ( " Could not load a texture for entry in 3ds file " ,
Materials [ i ] . Filename [ 3 ] . c_str ( ) , ELL_WARNING ) ;
}
else
{
2007-09-20 08:33:36 -07:00
m - > getMaterial ( ) . setTexture ( 1 , m - > getMaterial ( ) . getTexture ( 0 ) ) ;
m - > getMaterial ( ) . setTexture ( 0 , texture ) ;
2007-06-02 04:09:32 -07:00
m - > getMaterial ( ) . MaterialType = video : : EMT_REFLECTION_2_LAYER ;
2007-05-20 11:03:49 -07:00
}
}
if ( Materials [ i ] . Filename [ 4 ] . size ( ) )
{
2008-02-25 09:44:12 -08:00
video : : ITexture * texture = SceneManager - > getVideoDriver ( ) - > getTexture ( Materials [ i ] . Filename [ 4 ] . c_str ( ) ) ;
2007-06-02 04:09:32 -07:00
if ( ! texture )
2007-05-20 11:03:49 -07:00
{
core : : stringc fname = getTextureFileName (
Materials [ i ] . Filename [ 4 ] , modelFilename ) ;
if ( fname . size ( ) )
2008-02-25 09:44:12 -08:00
texture = SceneManager - > getVideoDriver ( ) - > getTexture ( fname . c_str ( ) ) ;
2007-05-20 11:03:49 -07:00
}
2007-06-02 04:09:32 -07:00
if ( ! texture )
2007-05-20 11:03:49 -07:00
os : : Printer : : log ( " Could not load a texture for entry in 3ds file " ,
Materials [ i ] . Filename [ 4 ] . c_str ( ) , ELL_WARNING ) ;
else
{
2007-09-20 08:33:36 -07:00
m - > getMaterial ( ) . setTexture ( 1 , texture ) ;
2008-02-25 09:44:12 -08:00
SceneManager - > getVideoDriver ( ) - > makeNormalMapTexture ( texture , Materials [ i ] . Strength [ 4 ] ) ;
2007-06-02 04:09:32 -07:00
m - > getMaterial ( ) . MaterialType = video : : EMT_PARALLAX_MAP_SOLID ;
2008-02-25 09:44:12 -08:00
m - > getMaterial ( ) . MaterialTypeParam = .035f ;
2007-05-20 11:03:49 -07:00
}
}
m - > drop ( ) ;
}
}
void C3DSMeshFileLoader : : cleanUp ( )
{
delete [ ] Vertices ;
CountVertices = 0 ;
Vertices = 0 ;
delete [ ] Indices ;
Indices = 0 ;
CountFaces = 0 ;
2007-08-28 15:37:57 -07:00
delete [ ] SmoothingGroups ;
SmoothingGroups = 0 ;
2007-05-20 11:03:49 -07:00
delete [ ] TCoords ;
TCoords = 0 ;
CountTCoords = 0 ;
MaterialGroups . clear ( ) ;
}
void C3DSMeshFileLoader : : readTextureCoords ( io : : IReadFile * file , ChunkData & data )
{
file - > read ( & CountTCoords , sizeof ( CountTCoords ) ) ;
# ifdef __BIG_ENDIAN__
CountTCoords = os : : Byteswap : : byteswap ( CountTCoords ) ;
# endif
data . read + = sizeof ( CountTCoords ) ;
s32 tcoordsBufferByteSize = CountTCoords * sizeof ( f32 ) * 2 ;
if ( data . header . length - data . read ! = tcoordsBufferByteSize )
{
os : : Printer : : log ( " Invalid size of tcoords found in 3ds file. " , ELL_WARNING ) ;
return ;
}
TCoords = new f32 [ CountTCoords * 3 ] ;
file - > read ( TCoords , tcoordsBufferByteSize ) ;
# ifdef __BIG_ENDIAN__
for ( int i = 0 ; i < CountTCoords * 2 ; i + + ) TCoords [ i ] = os : : Byteswap : : byteswap ( TCoords [ i ] ) ;
# endif
data . read + = tcoordsBufferByteSize ;
}
void C3DSMeshFileLoader : : readMaterialGroup ( io : : IReadFile * file , ChunkData & data )
{
SMaterialGroup group ;
readString ( file , data , group . MaterialName ) ;
file - > read ( & group . faceCount , sizeof ( group . faceCount ) ) ;
# ifdef __BIG_ENDIAN__
group . faceCount = os : : Byteswap : : byteswap ( group . faceCount ) ;
# endif
data . read + = sizeof ( group . faceCount ) ;
// read faces
2007-08-15 08:55:20 -07:00
group . faces = new u16 [ group . faceCount ] ;
file - > read ( group . faces , sizeof ( u16 ) * group . faceCount ) ;
2007-05-20 11:03:49 -07:00
# ifdef __BIG_ENDIAN__
2007-08-15 08:55:20 -07:00
for ( u32 i = 0 ; i < group . faceCount ; + + i )
group . faces [ i ] = os : : Byteswap : : byteswap ( group . faces [ i ] ) ;
2007-05-20 11:03:49 -07:00
# endif
2007-08-15 08:55:20 -07:00
data . read + = sizeof ( u16 ) * group . faceCount ;
2007-05-20 11:03:49 -07:00
MaterialGroups . push_back ( group ) ;
}
void C3DSMeshFileLoader : : readIndices ( io : : IReadFile * file , ChunkData & data )
{
file - > read ( & CountFaces , sizeof ( CountFaces ) ) ;
# ifdef __BIG_ENDIAN__
CountFaces = os : : Byteswap : : byteswap ( CountFaces ) ;
# endif
data . read + = sizeof ( CountFaces ) ;
s32 indexBufferByteSize = CountFaces * sizeof ( u16 ) * 4 ;
// Indices are u16s.
// After every 3 Indices in the array, there follows an edge flag.
Indices = new u16 [ CountFaces * 4 ] ;
file - > read ( Indices , indexBufferByteSize ) ;
# ifdef __BIG_ENDIAN__
2007-08-28 15:37:57 -07:00
for ( int i = 0 ; i < CountFaces * 4 ; + + i )
Indices [ i ] = os : : Byteswap : : byteswap ( Indices [ i ] ) ;
2007-05-20 11:03:49 -07:00
# endif
data . read + = indexBufferByteSize ;
}
void C3DSMeshFileLoader : : readVertices ( io : : IReadFile * file , ChunkData & data )
{
file - > read ( & CountVertices , sizeof ( CountVertices ) ) ;
# ifdef __BIG_ENDIAN__
CountVertices = os : : Byteswap : : byteswap ( CountVertices ) ;
# endif
data . read + = sizeof ( CountVertices ) ;
s32 vertexBufferByteSize = CountVertices * sizeof ( f32 ) * 3 ;
if ( data . header . length - data . read ! = vertexBufferByteSize )
{
os : : Printer : : log ( " Invalid size of vertices found in 3ds file. " , ELL_WARNING ) ;
return ;
}
Vertices = new f32 [ CountVertices * 3 ] ;
file - > read ( Vertices , vertexBufferByteSize ) ;
# ifdef __BIG_ENDIAN__
for ( int i = 0 ; i < CountVertices * 3 ; i + + ) Vertices [ i ] = os : : Byteswap : : byteswap ( Vertices [ i ] ) ;
# endif
data . read + = vertexBufferByteSize ;
}
void C3DSMeshFileLoader : : readChunkData ( io : : IReadFile * file , ChunkData & data )
{
file - > read ( & data . header , sizeof ( ChunkHeader ) ) ;
# ifdef __BIG_ENDIAN__
data . header . id = os : : Byteswap : : byteswap ( data . header . id ) ;
data . header . length = os : : Byteswap : : byteswap ( data . header . length ) ;
# endif
data . read + = sizeof ( ChunkHeader ) ;
}
void C3DSMeshFileLoader : : readString ( io : : IReadFile * file , ChunkData & data , core : : stringc & out )
{
c8 c = 1 ;
out = " " ;
while ( c )
{
file - > read ( & c , sizeof ( c8 ) ) ;
if ( c )
out . append ( c ) ;
+ + data . read ;
}
}
} // end namespace scene
} // end namespace irr
2007-09-04 11:51:42 -07:00
# endif // _IRR_COMPILE_WITH_3DS_LOADER_