- added Halflife 1 Model Loader

- added Halflife 1 Texture Loader
- slightly changed usage of getMesh ( doesn't effect existing implementation)

git-svn-id: svn://svn.code.sf.net/p/irrlicht/code/trunk@3335 dfc29bdd-3216-0410-991c-e03cc46cb475
master
engineer_apple 2010-07-07 16:16:03 +00:00
parent ccfcd68a12
commit 816d5655fc
23 changed files with 3115 additions and 30 deletions

View File

@ -11,6 +11,84 @@ Changes in 1.7.1 (05.07.2010) TA
changed the light billboards to use the light color. ( green light, green particle, red light red particle )
allow to disable the bump/parallax on the earth like in the room ( with transparency )
- added DDS Image files, DXT2, DXT3, DXT4, DXT5, based on code from nvidia and Randy Reddig
- added a Halflife 1 Model Loader. ( bases on code by Fabio Concas )
-> Load all Textures ( can even optimize it to texture atlas ), all bone animation, all submodels.
-> But to make use of the values ( named animation, mouth animation ) the Interface for IAnimatedMeshSceneNode
has to be reonde. I don't want to blow up the Interface again...
TODO:
->can handle float frames numbers, the interface for getMesh should be reworked
I already have working implementations for MD2, MD3 and MDL to use float blendning instead
of using some kind of fix point..
This is my idea of a new getMesh interface for IAnimatedMesh
//! Returns the IMesh interface for a frame.
/** \param frameA: Frame number as zero based index.
The Blend Factor is in the fractional part of frameA
The Mesh will be calculated as
frame = integer(frameA) * (1-fractional(frameA )) + frameB * fractional(frameA)
FrameNr KeyFrameA KeyFrameB
40.0 1 0
40.1 0.9 0.1
40.5 0.5 0.5
40.9 0.1 0.9
41.0 0 1
\param frameB: Frame number as zero based index. The other KeyFrame which is blended with FrameA.
\param userParam: for Example Level of detail, or something else
*/
virtual IMesh* getMesh(f32 frameA, s32 frameB = 0,s32 param = 0) = 0;
Should be discussed. handles all situations ( forward/reverse animation ) because the direction
vector is A->B
For now i used the (unused, always 255) detail level parameter and set a blend percentage as
s32 frameNr = (s32) getFrameNr();
s32 frameBlend = (s32) (core::fract ( getFrameNr() ) * 1000.f);
return Mesh->getMesh(frameNr, frameBlend, StartFrame, EndFrame);
So no interface is affected.
TODO:
I also added structures (suggestion) for Keyframe Interpolation which are currently not used here
mainly to unifiy get and set named animations/bones from different model files with a unique function call.
It would also effect the Handling of IAnimatedMeshSceneNode. This Topic should be discussed.
My goal is to get as many information from the original model file like key/bone animation, skin info, shaders
sub models, attachement points etc in a public interface
and to reduce the interface like setMD2Anim, setMD3Animn, setBoneAnim into one slim line function call
for setting and getting.
The callback interface also should be more generalized and event based.
(Halflife for example can notify if your left foot animation touches ground, or tirggers sound or whatever)
Maybe we use the gui event system for that
I included a 357kb Yodan.mdl and the copyright info file from Doug Hillyer to the media directory
used in example 7. collision as 4th model..
it's not easy to unify different model types and that's why it's not finished;-)
-> TODO: Quaternion Rotation is done private hand made and should be done with irrlicht quaterions
- added Halflife 1 Texture Loader
Valve uses WAL archive types like quake2. textures are inside model files
I reworked the existing ImageloaderWAL and added named Halflife textures to wal2 ( they have not extension )
and an LMP (palette/texture) loader into the same file ( all using 32bit now )
- coreutil.h
added void splitFilenam, splits a path into components
- irstring.h
added parameter make_lower to substring ( copy just lower case )
string<T> subString(u32 begin, s32 length, bool make_lower = false ) const
- ColorConverter
added
//! converts a 8 bit palettized or non palettized image (A8) into R8G8B8
static void convert8BitTo24Bit(const u8* in, s16* out, s32 width, s32 height, const s32* palette, s32 linepad = 0, bool flip=false);
//! converts a 8 bit palettized or non palettized image (A8) into A8R8G8B8
static void convert8BitTo32Bit(const u8* in, u8* out, s32 width, s32 height, const u8* palette, s32 linepad = 0, bool flip=false);
--------------------------------------
@ -573,7 +651,7 @@ Changes in 1.6 (23.09.2009)
There exists a known list of ArchiveLoaders, which know how to produce a Archive.
The Loaders and the Archives can be attached/detached on runtime.
The FileNames are now stored as core::string<c16>. where c16 is toggled between char/wchar
The FileNames are now stored as io::path. where c16 is toggled between char/wchar
with the #define flag _IRR_WCHAR_FILESYSTEM, to supported unicode backends (default:off)
Replaced most (const c8* filename) to string references.

View File

@ -164,14 +164,15 @@ int main()
selection is being performed. */
scene::IAnimatedMeshSceneNode* node = 0;
video::SMaterial material;
// Add an MD2 node, which uses vertex-based animation.
node = smgr->addAnimatedMeshSceneNode(smgr->getMesh("../../media/faerie.md2"),
0, IDFlag_IsPickable | IDFlag_IsHighlightable);
node->setPosition(core::vector3df(-70,-15,-120)); // Put its feet on the floor.
node->setPosition(core::vector3df(-70,-15,-140)); // Put its feet on the floor.
node->setScale(core::vector3df(2, 2, 2)); // Make it appear realistically scaled
node->setMD2Animation(scene::EMAT_POINT);
node->setAnimationSpeed(20.f);
video::SMaterial material;
material.setTexture(0, driver->getTexture("../../media/faerie2.bmp"));
material.Lighting = true;
material.NormalizeNormals = true;
@ -183,24 +184,38 @@ int main()
node->setTriangleSelector(selector);
selector->drop(); // We're done with this selector, so drop it now.
// This X files uses skeletal animation, but without skinning.
node = smgr->addAnimatedMeshSceneNode(smgr->getMesh("../../media/dwarf.x"),
0, IDFlag_IsPickable | IDFlag_IsHighlightable);
node->setPosition(core::vector3df(-70,-66,0)); // Put its feet on the floor.
node->setRotation(core::vector3df(0,-90,0)); // And turn it towards the camera.
node->setAnimationSpeed(20.f);
selector = smgr->createTriangleSelector(node);
node->setTriangleSelector(selector);
selector->drop();
// And this B3D file uses skinned skeletal animation.
node = smgr->addAnimatedMeshSceneNode(smgr->getMesh("../../media/ninja.b3d"),
0, IDFlag_IsPickable | IDFlag_IsHighlightable);
node->setScale(core::vector3df(10, 10, 10));
node->setPosition(core::vector3df(-70,-66,-60));
node->setPosition(core::vector3df(-70,-66,-80));
node->setRotation(core::vector3df(0,90,0));
node->setAnimationSpeed(10.f);
node->getMaterial(0).NormalizeNormals = true;
node->getMaterial(0).Lighting = true;
// Just do the same as we did above.
selector = smgr->createTriangleSelector(node);
node->setTriangleSelector(selector);
selector->drop();
// This X files uses skeletal animation, but without skinning.
node = smgr->addAnimatedMeshSceneNode(smgr->getMesh("../../media/dwarf.x"),
0, IDFlag_IsPickable | IDFlag_IsHighlightable);
node->setPosition(core::vector3df(-70,-66,-30)); // Put its feet on the floor.
node->setRotation(core::vector3df(0,-90,0)); // And turn it towards the camera.
node->setAnimationSpeed(20.f);
node->getMaterial(0).Lighting = true;
selector = smgr->createTriangleSelector(node);
node->setTriangleSelector(selector);
selector->drop();
// And this mdl file uses skinned skeletal animation.
node = smgr->addAnimatedMeshSceneNode(smgr->getMesh("../../media/yodan.mdl"),
0, IDFlag_IsPickable | IDFlag_IsHighlightable);
node->setPosition(core::vector3df(-70,-25,20));
node->getMaterial(0).Lighting = true;
// Just do the same as we did above.
selector = smgr->createTriangleSelector(node);
node->setTriangleSelector(selector);
@ -310,3 +325,4 @@ int main()
/*
**/

View File

@ -25,7 +25,7 @@ using namespace irr;
int main()
{
// ask if user would like shadows
/*
char i;
printf("Please press 'y' if you want to use realtime shadows.\n");
@ -37,6 +37,9 @@ int main()
video::E_DRIVER_TYPE driverType=driverChoiceConsole();
if (driverType==video::EDT_COUNT)
return 1;
*/
video::E_DRIVER_TYPE driverType = video::EDT_DIRECT3D9; // video::EDT_BURNINGSVIDEO; // video::EDT_OPENGL; //video::EDT_BURNINGSVIDEO;
bool shadows = true;
/*
Create device and exit if creation failed. We make the stencil flag

View File

@ -47,10 +47,105 @@ namespace scene
can be loaded directly by Irrlicht */
EAMT_OCT,
//! Halflife MDL model file
EAMT_MDL_HALFLIFE,
//! generic skinned mesh
EAMT_SKINNED
};
//! Possible types of Animation Type
enum E_ANIMATION_TYPE
{
//! No Animation
EAMT_STILL,
//! From Start to End, then Stop ( Limited Line )
EAMT_WAYPOINT,
//! Linear Cycling Animation ( Sawtooth )
EAMT_LOOPING,
//! Linear bobbing ( Triangle )
EAMT_PINGPONG,
};
//! Names for Animation Type
const c8* const MeshAnimationTypeNames[] =
{
"still",
"waypoint",
"looping",
"pingpong",
0
};
//! Data for holding named Animation Info
struct KeyFrameInterpolation
{
core::stringc Name; // Name of the current Animation/Bone
E_ANIMATION_TYPE AnimationType; // Type of Animation ( looping, usw..)
f32 CurrentFrame; // Current Frame
s32 NextFrame; // Frame which will be used next. For blending
s32 StartFrame; // Absolute Frame where the current animation start
s32 Frames; // Relative Frames how much Frames this animation have
s32 LoopingFrames; // How much of Frames sould be looped
s32 EndFrame; // Absolute Frame where the current animation ends End = start + frames - 1
f32 FramesPerSecond; // Speed in Frames/Seconds the animation is played
f32 RelativeSpeed; // Factor Original fps is modified
u32 BeginTime; // Animation started at this thime
u32 EndTime; // Animation end at this time
u32 LastTime; // Last Keyframe was done at this time
KeyFrameInterpolation ( const c8 * name = "", s32 start = 0, s32 frames = 0, s32 loopingframes = 0,
f32 fps = 0.f, f32 relativefps = 1.f )
: Name ( name ), AnimationType ( loopingframes ? EAMT_LOOPING : EAMT_WAYPOINT),
StartFrame ( start ), CurrentFrame ( (f32) start ), NextFrame ( start ),
Frames ( frames ), EndFrame ( start + frames - 1 ),
FramesPerSecond ( fps ), RelativeSpeed ( relativefps ),
LoopingFrames ( loopingframes ),
BeginTime ( 0 ), EndTime ( 0 ), LastTime ( 0 )
{
}
// linear search
bool operator == ( const KeyFrameInterpolation & other ) const
{
return Name.equals_ignore_case ( other.Name );
}
};
//! a List holding named Animations
typedef core::array < KeyFrameInterpolation > IAnimationList;
//! a List holding named Skins
typedef core::array < core::stringc > ISkinList;
// Current Model per Body
struct SubModel
{
core::stringc name;
u32 startBuffer;
u32 endBuffer;
u32 state;
};
struct BodyPart
{
core::stringc name;
u32 defaultModel;
core::array < SubModel > model;
};
//! a List holding named Models and SubModels
typedef core::array < BodyPart > IBodyList;
//! Interface for an animated mesh.
/** There are already simple implementations of this interface available so
you don't have to implement this interface on your own if you need to:

View File

@ -260,12 +260,12 @@ B3D, MS3D or X meshes */
//! Define _IRR_COMPILE_WITH_IRR_MESH_LOADER_ if you want to load Irrlicht Engine .irrmesh files
#define _IRR_COMPILE_WITH_IRR_MESH_LOADER_
//! Define _IRR_COMPILE_WITH_HALFLIFE_LOADER_ if you want to load Halflife animated files
#define _IRR_COMPILE_WITH_HALFLIFE_LOADER_
//! Define _IRR_COMPILE_WITH_MD2_LOADER_ if you want to load Quake 2 animated files
#define _IRR_COMPILE_WITH_MD2_LOADER_
//! Define _IRR_COMPILE_WITH_MD3_LOADER_ if you want to load Quake 3 animated files
#define _IRR_COMPILE_WITH_MD3_LOADER_
//! Define _IRR_COMPILE_WITH_3DS_LOADER_ if you want to load 3D Studio Max files
#define _IRR_COMPILE_WITH_3DS_LOADER_
//! Define _IRR_COMPILE_WITH_COLLADA_LOADER_ if you want to load Collada files
@ -321,6 +321,8 @@ B3D, MS3D or X meshes */
#define _IRR_COMPILE_WITH_TGA_LOADER_
//! Define _IRR_COMPILE_WITH_WAL_LOADER_ if you want to load .wal files
#define _IRR_COMPILE_WITH_WAL_LOADER_
//! Define _IRR_COMPILE_WITH_LMP_LOADER_ if you want to load .lmp files
#define _IRR_COMPILE_WITH_LMP_LOADER_
//! Define _IRR_COMPILE_WITH_RGB_LOADER_ if you want to load Silicon Graphics .rgb/.rgba/.sgi/.int/.inta/.bw files
#define _IRR_COMPILE_WITH_RGB_LOADER_

View File

@ -33,6 +33,16 @@ namespace scene
MeshBuffers[i]->drop();
}
//! clean mesh
virtual void clear()
{
for (u32 i=0; i<MeshBuffers.size(); ++i)
MeshBuffers[i]->drop();
MeshBuffers.clear();
BoundingBox.reset ( 0.f, 0.f, 0.f );
}
//! returns amount of mesh buffers.
virtual u32 getMeshBufferCount() const
{

View File

@ -138,6 +138,39 @@ inline s32 isInSameDirectory ( const io::path& path, const io::path& file )
return subB - subA;
}
// splits a path into components
static inline void splitFilename( const io::path &name, io::path *path,io::path* filename, io::path* extension,bool make_lower = false )
{
s32 i = name.size();
s32 extpos = i;
// search for path separator or beginning
while ( i >= 0 )
{
if ( name[i] == '.' )
{
extpos = i;
if ( extension )
*extension = name.subString ( extpos + 1, name.size() - (extpos + 1), make_lower );
}
else
if ( name[i] == '/' || name[i] == '\\' )
{
if ( filename )
*filename = name.subString ( i + 1, extpos - (i + 1), make_lower );
if ( path )
{
*path = name.subString ( 0, i + 1, make_lower );
path->replace ( '\\', '/' );
}
return;
}
i -= 1;
}
if ( filename )
*filename = name.subString ( 0, extpos, make_lower );
}
//! some standard function ( to remove dependencies )
#undef isdigit

View File

@ -884,25 +884,35 @@ public:
//! Returns a substring
/** \param begin: Start of substring.
\param length: Length of substring. */
string<T,TAlloc> subString(u32 begin, s32 length) const
\param length: Length of substring.
\param make_lower, copy only lower case */
string<T> subString(u32 begin, s32 length, bool make_lower = false ) const
{
// if start after string
// or no proper substring length
if ((length <= 0) || (begin>=size()))
return string<T,TAlloc>("");
return string<T>("");
// clamp length to maximal value
if ((length+begin) > size())
length = size()-begin;
string<T,TAlloc> o;
string<T> o;
o.reserve(length+1);
for (s32 i=0; i<length; ++i)
o.array[i] = array[i+begin];
s32 i;
if ( !make_lower )
{
for (i=0; i<length; ++i)
o.array[i] = array[i+begin];
}
else
{
for (i=0; i<length; ++i)
o.array[i] = locale_lower ( array[i+begin] );
}
o.array[length] = 0;
o.used = o.allocated;
o.used = length + 1;
return o;
}

View File

@ -0,0 +1,36 @@
Boba Fett Model for Half-Life
Copyright © 1999 Doug Hillyer
Author: Doug "CHaoSMaN" Hillyer--All modeling and textures
E-Mail: dhillyer@bigfoot.com
ICQ: 707847 (Don't contact through ICQ without a good reason)
Webpage: http:// *UNDER CONSTRUCTION* E-mail me if you'll host my page.
Model Name: Boba Fett
Version: 1.0
Relaese Date: 3/24/99
Total Size: 448KB
Polygons: 700
Vertices: 379
Texture Size: 159KB (I'll take it down under 150KB in the next release)
Team Colors: No. Maybe in a future release if I figure out how to change the palette.
Animations: Standard DM Player Animations--I'm too lazy to make my own
Build Time: 30+ Hours?
Programs Used: 3D Studio MAX R2.5, Character Studio R2, Surface Suite 1.1, Photoshop 5
Knows bugs:
Top of jet pack goes though his head in some animations. Not much I can do about it. No chrome texture. If anyone knows how to do this, let me know and I'll add it. Multiplayer BMP thinks it has team colors and doesn't display correctly.
Description:
Here is one less model on the Cold Fusion Wish List (http://www.planethalflife.com/coldfusion/)! After more that 30 hours of modeling and texturing it's finaly done. Each and every polygon hand-built by me, except for the arms, which belong to the gordon model. I saw no reason to remodel something that was already made. All textures made to match the latest version of Boba Fett. The modifier stack in 3DSMAX had at least 40 modifiers and froze my computer numerous time. It's a little bit bulky at 700 polygons, but I can't do it with much less and still have all of the details that I want. I hope that everyone likes it. Please send me any comments or suggestions you may have.
If there is something wronge with the design or model, then let me know so that I can fix it in an upcoming release.
I'm also taking requests or suggestions for models.
Remember, this model is Copyrighted by me, Doug Hillyer. If you want to use this model or need one custom built for a MOD, then contact me.
Enjoy!
Installation:
Put all files (bobafett.mdl, bobafett.bmp) in half-life\valve\models\player\bobafett directory

BIN
media/yodan.mdl Normal file

Binary file not shown.

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,536 @@
// Copyright (C) 2002-2010 Thomas Alten
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#ifndef __C_ANIMATED_MESH_HALFLIFE_H_INCLUDED__
#define __C_ANIMATED_MESH_HALFLIFE_H_INCLUDED__
#include "IAnimatedMesh.h"
#include "ISceneManager.h"
#include "irrArray.h"
#include "irrString.h"
#include "IMeshLoader.h"
#include "SMesh.h"
#include "IReadFile.h"
namespace irr
{
namespace scene
{
#if defined(_MSC_VER) || defined(__BORLANDC__) || defined (__BCPLUSPLUS__)
# pragma pack( push, packing )
# pragma pack( 1 )
# define PACK_STRUCT
#elif defined( __GNUC__ )
# define PACK_STRUCT __attribute__((packed))
#else
# error compiler not supported
#endif
// STUDIO MODELS, Copyright (c) 1998, Valve LLC. All rights reserved.
#define MAXSTUDIOTRIANGLES 20000 // TODO: tune this
#define MAXSTUDIOVERTS 2048 // TODO: tune this
#define MAXSTUDIOSEQUENCES 256 // total animation sequences
#define MAXSTUDIOSKINS 100 // total textures
#define MAXSTUDIOSRCBONES 512 // bones allowed at source movement
#define MAXSTUDIOBONES 128 // total bones actually used
#define MAXSTUDIOMODELS 32 // sub-models per model
#define MAXSTUDIOBODYPARTS 32
#define MAXSTUDIOGROUPS 4
#define MAXSTUDIOANIMATIONS 512 // per sequence
#define MAXSTUDIOMESHES 256
#define MAXSTUDIOEVENTS 1024
#define MAXSTUDIOPIVOTS 256
#define MAXSTUDIOCONTROLLERS 8
typedef f32 vec3_hl[3]; // x,y,z
typedef f32 vec4_hl[4]; // x,y,z,w
struct SHalflifeHeader
{
c8 id[4];
s32 version;
c8 name[64];
s32 length;
vec3_hl eyeposition; // ideal eye position
vec3_hl min; // ideal movement hull size
vec3_hl max;
vec3_hl bbmin; // clipping bounding box
vec3_hl bbmax;
s32 flags;
u32 numbones; // bones
u32 boneindex;
u32 numbonecontrollers; // bone controllers
u32 bonecontrollerindex;
u32 numhitboxes; // complex bounding boxes
u32 hitboxindex;
u32 numseq; // animation sequences
u32 seqindex;
u32 numseqgroups; // demand loaded sequences
u32 seqgroupindex;
u32 numtextures; // raw textures
u32 textureindex;
u32 texturedataindex;
u32 numskinref; // replaceable textures
u32 numskinfamilies;
u32 skinindex;
u32 numbodyparts;
u32 bodypartindex;
u32 numattachments; // queryable attachable points
u32 attachmentindex;
s32 soundtable;
s32 soundindex;
s32 soundgroups;
s32 soundgroupindex;
s32 numtransitions; // animation node to animation node transition graph
s32 transitionindex;
};
// header for demand loaded sequence group data
typedef struct
{
s32 id;
s32 version;
c8 name[64];
s32 length;
} studioseqhdr_t;
// bones
struct SHalflifeBone
{
c8 name[32]; // bone name for symbolic links
s32 parent; // parent bone
s32 flags; // ??
s32 bonecontroller[6]; // bone controller index, -1 == none
f32 value[6]; // default DoF values
f32 scale[6]; // scale for delta DoF values
};
// bone controllers
struct SHalflifeBoneController
{
s32 bone; // -1 == 0
s32 type; // X, Y, Z, XR, YR, ZR, M
f32 start;
f32 end;
s32 rest; // byte index value at rest
s32 index; // 0-3 user set controller, 4 mouth
};
// intersection boxes
struct SHalflifeBBox
{
s32 bone;
s32 group; // intersection group
vec3_hl bbmin; // bounding box
vec3_hl bbmax;
};
#ifndef ZONE_H
typedef void *cache_user_t;
#endif
// demand loaded sequence groups
struct SHalflifeSequenceGroup
{
c8 label[32]; // textual name
c8 name[64]; // file name
cache_user_t cache; // cache index pointer
s32 data; // hack for group 0
};
// sequence descriptions
struct SHalflifeSequence
{
c8 label[32]; // sequence label
f32 fps; // frames per second
s32 flags; // looping/non-looping flags
s32 activity;
s32 actweight;
s32 numevents;
s32 eventindex;
s32 numframes; // number of frames per sequence
u32 numpivots; // number of foot pivots
u32 pivotindex;
s32 motiontype;
s32 motionbone;
vec3_hl linearmovement;
s32 automoveposindex;
s32 automoveangleindex;
vec3_hl bbmin; // per sequence bounding box
vec3_hl bbmax;
s32 numblends;
s32 animindex; // SHalflifeAnimOffset pointer relative to start of sequence group data
// [blend][bone][X, Y, Z, XR, YR, ZR]
s32 blendtype[2]; // X, Y, Z, XR, YR, ZR
f32 blendstart[2]; // starting value
f32 blendend[2]; // ending value
s32 blendparent;
s32 seqgroup; // sequence group for demand loading
s32 entrynode; // transition node at entry
s32 exitnode; // transition node at exit
s32 nodeflags; // transition rules
s32 nextseq; // auto advancing sequences
};
// events
typedef struct
{
s32 frame;
s32 event;
s32 type;
c8 options[64];
} mstudioevent_t;
// pivots
typedef struct
{
vec3_hl org; // pivot point
s32 start;
s32 end;
} mstudiopivot_t;
// attachment
struct SHalfelifeAttachment
{
c8 name[32];
s32 type;
s32 bone;
vec3_hl org; // attachment point
vec3_hl vectors[3];
};
struct SHalflifeAnimOffset
{
u16 offset[6];
};
// animation frames
union SHalfelifeAnimationFrame
{
struct {
u8 valid;
u8 total;
} num;
s16 value;
};
// body part index
struct SHalflifeBody
{
c8 name[64];
u32 nummodels;
u32 base;
u32 modelindex; // index into models array
};
// skin info
struct SHalflifeTexture
{
c8 name[64];
s32 flags;
s32 width;
s32 height;
s32 index;
};
// skin families
// short index[skinfamilies][skinref]
// studio models
struct SHalflifeModel
{
c8 name[64];
s32 type;
f32 boundingradius;
u32 nummesh;
u32 meshindex;
u32 numverts; // number of unique vertices
u32 vertinfoindex; // vertex bone info
u32 vertindex; // vertex vec3_hl
u32 numnorms; // number of unique surface normals
u32 norminfoindex; // normal bone info
u32 normindex; // normal vec3_hl
u32 numgroups; // deformation groups
u32 groupindex;
};
// meshes
typedef struct
{
u32 numtris;
u32 triindex;
u32 skinref;
u32 numnorms; // per mesh normals
u32 normindex; // normal vec3_hl
} SHalflifeMesh;
// lighting options
#define STUDIO_NF_FLATSHADE 0x0001
#define STUDIO_NF_CHROME 0x0002
#define STUDIO_NF_FULLBRIGHT 0x0004
// motion flags
#define STUDIO_X 0x0001
#define STUDIO_Y 0x0002
#define STUDIO_Z 0x0004
#define STUDIO_XR 0x0008
#define STUDIO_YR 0x0010
#define STUDIO_ZR 0x0020
#define STUDIO_LX 0x0040
#define STUDIO_LY 0x0080
#define STUDIO_LZ 0x0100
#define STUDIO_AX 0x0200
#define STUDIO_AY 0x0400
#define STUDIO_AZ 0x0800
#define STUDIO_AXR 0x1000
#define STUDIO_AYR 0x2000
#define STUDIO_AZR 0x4000
#define STUDIO_TYPES 0x7FFF
#define STUDIO_RLOOP 0x8000 // controller that wraps shortest distance
// sequence flags
#define STUDIO_LOOPING 0x0001
// bone flags
#define STUDIO_HAS_NORMALS 0x0001
#define STUDIO_HAS_VERTICES 0x0002
#define STUDIO_HAS_BBOX 0x0004
#define STUDIO_HAS_CHROME 0x0008 // if any of the textures have chrome on them
#define RAD_TO_STUDIO (32768.0/M_PI)
#define STUDIO_TO_RAD (M_PI/32768.0)
// Default alignment
#if defined(_MSC_VER) || defined(__BORLANDC__) || defined (__BCPLUSPLUS__)
# pragma pack( pop, packing )
#endif
#undef PACK_STRUCT
/*!
Textureatlas
Combine Source Images with arbitrary size and bithdepth to an Image with 2^n size
borders from the source images are copied around for allowing filtering ( bilinear, mipmap )
*/
struct STextureAtlas
{
STextureAtlas ()
{
release();
}
virtual ~STextureAtlas ()
{
release ();
}
void release ();
void addSource ( const c8 * name, video::IImage * image );
void create ( u32 pixelborder, video::E_TEXTURE_CLAMP texmode );
void getScale ( core::vector2df &scale );
void getTranslation ( const c8 * name, core::vector2di &pos );
struct TextureAtlasEntry
{
io::path name;
u32 width;
u32 height;
core::vector2di pos;
video::IImage * image;
bool operator < ( const TextureAtlasEntry & other )
{
return height > other.height;
}
};
core::array < TextureAtlasEntry > atlas;
video::IImage * Master;
};
class CAnimatedMeshHalfLife : public IAnimatedMesh
{
public:
//! constructor
CAnimatedMeshHalfLife( );
//! destructor
virtual ~CAnimatedMeshHalfLife();
//! loads a Halflife mdl file
virtual bool loadModelFile( io::IReadFile* file, ISceneManager * smgr );
//IAnimatedMesh
virtual u32 getFrameCount() const;
virtual IMesh* getMesh(s32 frame, s32 detailLevel, s32 startFrameLoop, s32 endFrameLoop);
virtual const core::aabbox3d<f32>& getBoundingBox() const;
virtual E_ANIMATED_MESH_TYPE getMeshType() const;
virtual void renderModel ( u32 param, video::IVideoDriver * driver, const core::matrix4 &absoluteTransformation);
//! returns amount of mesh buffers.
virtual u32 getMeshBufferCount() const;
//! returns pointer to a mesh buffer
virtual IMeshBuffer* getMeshBuffer(u32 nr) const;
//! Returns pointer to a mesh buffer which fits a material
virtual IMeshBuffer* getMeshBuffer( const video::SMaterial &material) const;
virtual void setMaterialFlag(video::E_MATERIAL_FLAG flag, bool newvalue);
//! set the hardware mapping hint, for driver
virtual void setHardwareMappingHint(E_HARDWARE_MAPPING newMappingHint, E_BUFFER_TYPE buffer=EBT_VERTEX_AND_INDEX);
//! flags the meshbuffer as changed, reloads hardware buffers
virtual void setDirty(E_BUFFER_TYPE buffer=EBT_VERTEX_AND_INDEX);
//! set user axis aligned bounding box
virtual void setBoundingBox(const core::aabbox3df& box);
//! Get the Animation List
virtual IAnimationList* getAnimList () { return &AnimList; }
//! Return the named Body List of this Animated Mesh
virtual IBodyList *getBodyList() { return &BodyList; }
private:
// KeyFrame Animation List
IAnimationList AnimList;
// Sum of all sequences
u32 FrameCount;
// Named meshes of the Body
IBodyList BodyList;
//! return a Mesh per frame
SMesh MeshIPol;
ISceneManager *SceneManager;
SHalflifeHeader *Header;
SHalflifeHeader *TextureHeader;
bool OwnTexModel; // do we have a modelT.mdl ?
SHalflifeHeader *AnimationHeader[32]; // sequences named model01.mdl, model02.mdl
void initData ();
void freeModel ();
SHalflifeHeader * loadModel( io::IReadFile* file, const io::path &filename );
bool postLoadModel( const io::path &filename );
u32 SequenceIndex; // sequence index
f32 CurrentFrame; // Current Frame
#define MOUTH_CONTROLLER 4
u8 BoneController[4 + 1 ]; // bone controllers + mouth position
u8 Blending[2]; // animation blending
f32 SetController( s32 controllerIndex, f32 value );
u32 SkinGroupSelection; // skin group selection
u32 SetSkin( u32 value );
void initModel ();
void dumpModelInfo ( u32 level);
void ExtractBbox( s32 sequence, core::aabbox3df &box );
void setUpBones ();
SHalflifeAnimOffset * getAnim( SHalflifeSequence *seq );
void slerpBones( vec4_hl q1[], vec3_hl pos1[], vec4_hl q2[], vec3_hl pos2[], f32 s );
void calcRotations ( vec3_hl *pos, vec4_hl *q, SHalflifeSequence *seq, SHalflifeAnimOffset *anim, f32 f );
vec4_hl BoneAdj;
void calcBoneAdj();
void calcBoneQuaternion( s32 frame, f32 s, SHalflifeBone *bone, SHalflifeAnimOffset *anim, f32 *q ) const;
void calcBonePosition( s32 frame, f32 s, SHalflifeBone *bone, SHalflifeAnimOffset *anim, f32 *pos ) const;
void buildVertices ();
io::path TextureBaseName;
#define HL_TEXTURE_ATLAS
#ifdef HL_TEXTURE_ATLAS
STextureAtlas TextureAtlas;
video::ITexture *TextureMaster;
#endif
};
//! Meshloader capable of loading HalfLife Model files
class CHalflifeMDLMeshFileLoader : public IMeshLoader
{
public:
//! Constructor
CHalflifeMDLMeshFileLoader( scene::ISceneManager* smgr );
//! returns true if the file maybe is able to be loaded by this class
//! based on the file extension (e.g. ".bsp")
virtual bool isALoadableFileExtension(const io::path& filename) const;
//! 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().
//! See IReferenceCounted::drop() for more information.
virtual IAnimatedMesh* createMesh(io::IReadFile* file);
private:
scene::ISceneManager* SceneManager;
};
} // end namespace scene
} // end namespace irr
#endif

View File

@ -199,7 +199,9 @@ IMesh * CAnimatedMeshSceneNode::getMeshForCurrentFrame()
{
if(Mesh->getMeshType() != EAMT_SKINNED)
{
return Mesh->getMesh((s32)getFrameNr(), 255, StartFrame, EndFrame);
s32 frameNr = (s32) getFrameNr();
s32 frameBlend = (s32) (core::fract ( getFrameNr() ) * 1000.f);
return Mesh->getMesh(frameNr, frameBlend, StartFrame, EndFrame);
}
else
{

View File

@ -112,6 +112,93 @@ void CColorConverter::convert8BitTo16Bit(const u8* in, s16* out, s32 width, s32
}
}
//! converts a 8 bit palettized or non palettized image (A8) into R8G8B8
void CColorConverter::convert8BitTo24Bit(const u8* in, u8* out, s32 width, s32 height, const u8* palette, s32 linepad, bool flip)
{
if (!in || !out )
return;
const s32 lineWidth = 3 * width;
if (flip)
out += lineWidth * height;
for (s32 y=0; y<height; ++y)
{
if (flip)
out -= lineWidth; // one line back
for (s32 x=0; x< lineWidth; x += 3)
{
if ( palette )
{
#ifdef __BIG_ENDIAN__
out[x+0] = palette[ (in[0] << 2 ) + 0];
out[x+1] = palette[ (in[0] << 2 ) + 1];
out[x+2] = palette[ (in[0] << 2 ) + 2];
#else
out[x+0] = palette[ (in[0] << 2 ) + 2];
out[x+1] = palette[ (in[0] << 2 ) + 1];
out[x+2] = palette[ (in[0] << 2 ) + 0];
#endif
}
else
{
out[x+0] = in[0];
out[x+1] = in[0];
out[x+2] = in[0];
}
++in;
}
if (!flip)
out += lineWidth;
in += linepad;
}
}
//! converts a 8 bit palettized or non palettized image (A8) into R8G8B8
void CColorConverter::convert8BitTo32Bit(const u8* in, u8* out, s32 width, s32 height, const u8* palette, s32 linepad, bool flip)
{
if (!in || !out )
return;
const u32 lineWidth = 4 * width;
if (flip)
out += lineWidth * height;
u32 x;
register u32 c;
for (u32 y=0; y < (u32) height; ++y)
{
if (flip)
out -= lineWidth; // one line back
if ( palette )
{
for (x=0; x < (u32) width; x += 1)
{
c = in[x];
((u32*)out)[x] = ((u32*)palette)[ c ];
}
}
else
{
for (x=0; x < (u32) width; x += 1)
{
c = in[x];
#ifdef __BIG_ENDIAN__
((u32*)out)[x] = c << 24 | c << 16 | c << 8 | 0x000000FF;
#else
((u32*)out)[x] = 0xFF000000 | c << 16 | c << 8 | c;
#endif
}
}
if (!flip)
out += lineWidth;
in += width + linepad;
}
}
//! converts 16bit data to 16bit data

View File

@ -26,6 +26,12 @@ public:
//! converts a 8 bit palettized image to A1R5G5B5
static void convert8BitTo16Bit(const u8* in, s16* out, s32 width, s32 height, const s32* palette, s32 linepad=0, bool flip=false);
//! converts a 8 bit palettized or non palettized image (A8) into R8G8B8
static void convert8BitTo24Bit(const u8* in, u8* out, s32 width, s32 height, const u8* palette, s32 linepad = 0, bool flip=false);
//! converts a 8 bit palettized or non palettized image (A8) into A8R8G8B8
static void convert8BitTo32Bit(const u8* in, u8* out, s32 width, s32 height, const u8* palette, s32 linepad = 0, bool flip=false);
//! converts R8G8B8 16 bit data to A1R5G5B5 data
static void convert16BitTo16Bit(const s16* in, s16* out, s32 width, s32 height, s32 linepad=0, bool flip=false);

View File

@ -122,7 +122,7 @@ void CStencilBuffer::setSize(const core::dimension2d<u32>& size)
if (Buffer)
delete [] Buffer;
Pitch = size.Width * sizeof ( u8 );
Pitch = size.Width * sizeof ( u32 );
TotalSize = Pitch * size.Height;
Buffer = new u8[TotalSize];
clear ();

View File

@ -18,6 +18,9 @@ namespace irr
namespace video
{
// old implementation
#if 0
// May or may not be fully implemented
#define TRY_LOADING_PALETTE_FROM_FILE 0
@ -141,6 +144,302 @@ IImageLoader* createImageLoaderWAL()
return new irr::video::CImageLoaderWAL();
}
#endif
// Palette quake2 colormap.h, 768 byte, last is transparent
static const u32 colormap_h[256] = {
0xFF000000,0xFF0F0F0F,0xFF1F1F1F,0xFF2F2F2F,0xFF3F3F3F,0xFF4B4B4B,0xFF5B5B5B,0xFF6B6B6B,
0xFF7B7B7B,0xFF8B8B8B,0xFF9B9B9B,0xFFABABAB,0xFFBBBBBB,0xFFCBCBCB,0xFFDBDBDB,0xFFEBEBEB,
0xFF0F0B07,0xFF170F0B,0xFF1F170B,0xFF271B0F,0xFF2F2313,0xFF372B17,0xFF3F2F17,0xFF4B371B,
0xFF533B1B,0xFF5B431F,0xFF634B1F,0xFF6B531F,0xFF73571F,0xFF7B5F23,0xFF836723,0xFF8F6F23,
0xFF0B0B0F,0xFF13131B,0xFF1B1B27,0xFF272733,0xFF2F2F3F,0xFF37374B,0xFF3F3F57,0xFF474767,
0xFF4F4F73,0xFF5B5B7F,0xFF63638B,0xFF6B6B97,0xFF7373A3,0xFF7B7BAF,0xFF8383BB,0xFF8B8BCB,
0xFF000000,0xFF070700,0xFF0B0B00,0xFF131300,0xFF1B1B00,0xFF232300,0xFF2B2B07,0xFF2F2F07,
0xFF373707,0xFF3F3F07,0xFF474707,0xFF4B4B0B,0xFF53530B,0xFF5B5B0B,0xFF63630B,0xFF6B6B0F,
0xFF070000,0xFF0F0000,0xFF170000,0xFF1F0000,0xFF270000,0xFF2F0000,0xFF370000,0xFF3F0000,
0xFF470000,0xFF4F0000,0xFF570000,0xFF5F0000,0xFF670000,0xFF6F0000,0xFF770000,0xFF7F0000,
0xFF131300,0xFF1B1B00,0xFF232300,0xFF2F2B00,0xFF372F00,0xFF433700,0xFF4B3B07,0xFF574307,
0xFF5F4707,0xFF6B4B0B,0xFF77530F,0xFF835713,0xFF8B5B13,0xFF975F1B,0xFFA3631F,0xFFAF6723,
0xFF231307,0xFF2F170B,0xFF3B1F0F,0xFF4B2313,0xFF572B17,0xFF632F1F,0xFF733723,0xFF7F3B2B,
0xFF8F4333,0xFF9F4F33,0xFFAF632F,0xFFBF772F,0xFFCF8F2B,0xFFDFAB27,0xFFEFCB1F,0xFFFFF31B,
0xFF0B0700,0xFF1B1300,0xFF2B230F,0xFF372B13,0xFF47331B,0xFF533723,0xFF633F2B,0xFF6F4733,
0xFF7F533F,0xFF8B5F47,0xFF9B6B53,0xFFA77B5F,0xFFB7876B,0xFFC3937B,0xFFD3A38B,0xFFE3B397,
0xFFAB8BA3,0xFF9F7F97,0xFF937387,0xFF8B677B,0xFF7F5B6F,0xFF775363,0xFF6B4B57,0xFF5F3F4B,
0xFF573743,0xFF4B2F37,0xFF43272F,0xFF371F23,0xFF2B171B,0xFF231313,0xFF170B0B,0xFF0F0707,
0xFFBB739F,0xFFAF6B8F,0xFFA35F83,0xFF975777,0xFF8B4F6B,0xFF7F4B5F,0xFF734353,0xFF6B3B4B,
0xFF5F333F,0xFF532B37,0xFF47232B,0xFF3B1F23,0xFF2F171B,0xFF231313,0xFF170B0B,0xFF0F0707,
0xFFDBC3BB,0xFFCBB3A7,0xFFBFA39B,0xFFAF978B,0xFFA3877B,0xFF977B6F,0xFF876F5F,0xFF7B6353,
0xFF6B5747,0xFF5F4B3B,0xFF533F33,0xFF433327,0xFF372B1F,0xFF271F17,0xFF1B130F,0xFF0F0B07,
0xFF6F837B,0xFF677B6F,0xFF5F7367,0xFF576B5F,0xFF4F6357,0xFF475B4F,0xFF3F5347,0xFF374B3F,
0xFF2F4337,0xFF2B3B2F,0xFF233327,0xFF1F2B1F,0xFF172317,0xFF0F1B13,0xFF0B130B,0xFF070B07,
0xFFFFF31B,0xFFEFDF17,0xFFDBCB13,0xFFCBB70F,0xFFBBA70F,0xFFAB970B,0xFF9B8307,0xFF8B7307,
0xFF7B6307,0xFF6B5300,0xFF5B4700,0xFF4B3700,0xFF3B2B00,0xFF2B1F00,0xFF1B0F00,0xFF0B0700,
0xFF0000FF,0xFF0B0BEF,0xFF1313DF,0xFF1B1BCF,0xFF2323BF,0xFF2B2BAF,0xFF2F2F9F,0xFF2F2F8F,
0xFF2F2F7F,0xFF2F2F6F,0xFF2F2F5F,0xFF2B2B4F,0xFF23233F,0xFF1B1B2F,0xFF13131F,0xFF0B0B0F,
0xFF2B0000,0xFF3B0000,0xFF4B0700,0xFF5F0700,0xFF6F0F00,0xFF7F1707,0xFF931F07,0xFFA3270B,
0xFFB7330F,0xFFC34B1B,0xFFCF632B,0xFFDB7F3B,0xFFE3974F,0xFFE7AB5F,0xFFEFBF77,0xFFF7D38B,
0xFFA77B3B,0xFFB79B37,0xFFC7C337,0xFFE7E357,0xFF7FBFFF,0xFFABE7FF,0xFFD7FFFF,0xFF670000,
0xFF8B0000,0xFFB30000,0xFFD70000,0xFFFF0000,0xFFFFF393,0xFFFFF7C7,0xFFFFFFFF,0x009F5B53
};
// Palette quake2 demo pics/colormap.pcx, last is transparent
static const u32 colormap_pcx[256] = {
0xFF000000,0xFF0F0F0F,0xFF1F1F1F,0xFF2F2F2F,0xFF3F3F3F,0xFF4B4B4B,0xFF5B5B5B,0xFF6B6B6B,
0xFF7B7B7B,0xFF8B8B8B,0xFF9B9B9B,0xFFABABAB,0xFFBBBBBB,0xFFCBCBCB,0xFFDBDBDB,0xFFEBEBEB,
0xFF634B23,0xFF5B431F,0xFF533F1F,0xFF4F3B1B,0xFF47371B,0xFF3F2F17,0xFF3B2B17,0xFF332713,
0xFF2F2313,0xFF2B1F13,0xFF271B0F,0xFF23170F,0xFF1B130B,0xFF170F0B,0xFF130F07,0xFF0F0B07,
0xFF5F5F6F,0xFF5B5B67,0xFF5B535F,0xFF574F5B,0xFF534B53,0xFF4F474B,0xFF473F43,0xFF3F3B3B,
0xFF3B3737,0xFF332F2F,0xFF2F2B2B,0xFF272727,0xFF232323,0xFF1B1B1B,0xFF171717,0xFF131313,
0xFF8F7753,0xFF7B6343,0xFF735B3B,0xFF674F2F,0xFFCF974B,0xFFA77B3B,0xFF8B672F,0xFF6F5327,
0xFFEB9F27,0xFFCB8B23,0xFFAF771F,0xFF93631B,0xFF774F17,0xFF5B3B0F,0xFF3F270B,0xFF231707,
0xFFA73B2B,0xFF9F2F23,0xFF972B1B,0xFF8B2713,0xFF7F1F0F,0xFF73170B,0xFF671707,0xFF571300,
0xFF4B0F00,0xFF430F00,0xFF3B0F00,0xFF330B00,0xFF2B0B00,0xFF230B00,0xFF1B0700,0xFF130700,
0xFF7B5F4B,0xFF735743,0xFF6B533F,0xFF674F3B,0xFF5F4737,0xFF574333,0xFF533F2F,0xFF4B372B,
0xFF433327,0xFF3F2F23,0xFF37271B,0xFF2F2317,0xFF271B13,0xFF1F170F,0xFF170F0B,0xFF0F0B07,
0xFF6F3B17,0xFF5F3717,0xFF532F17,0xFF432B17,0xFF372313,0xFF271B0F,0xFF1B130B,0xFF0F0B07,
0xFFB35B4F,0xFFBF7B6F,0xFFCB9B93,0xFFD7BBB7,0xFFCBD7DF,0xFFB3C7D3,0xFF9FB7C3,0xFF87A7B7,
0xFF7397A7,0xFF5B879B,0xFF47778B,0xFF2F677F,0xFF17536F,0xFF134B67,0xFF0F435B,0xFF0B3F53,
0xFF07374B,0xFF072F3F,0xFF072733,0xFF001F2B,0xFF00171F,0xFF000F13,0xFF00070B,0xFF000000,
0xFF8B5757,0xFF834F4F,0xFF7B4747,0xFF734343,0xFF6B3B3B,0xFF633333,0xFF5B2F2F,0xFF572B2B,
0xFF4B2323,0xFF3F1F1F,0xFF331B1B,0xFF2B1313,0xFF1F0F0F,0xFF130B0B,0xFF0B0707,0xFF000000,
0xFF979F7B,0xFF8F9773,0xFF878B6B,0xFF7F8363,0xFF777B5F,0xFF737357,0xFF6B6B4F,0xFF636347,
0xFF5B5B43,0xFF4F4F3B,0xFF434333,0xFF37372B,0xFF2F2F23,0xFF23231B,0xFF171713,0xFF0F0F0B,
0xFF9F4B3F,0xFF934337,0xFF8B3B2F,0xFF7F3727,0xFF772F23,0xFF6B2B1B,0xFF632317,0xFF571F13,
0xFF4F1B0F,0xFF43170B,0xFF37130B,0xFF2B0F07,0xFF1F0B07,0xFF170700,0xFF0B0000,0xFF000000,
0xFF777BCF,0xFF6F73C3,0xFF676BB7,0xFF6363A7,0xFF5B5B9B,0xFF53578F,0xFF4B4F7F,0xFF474773,
0xFF3F3F67,0xFF373757,0xFF2F2F4B,0xFF27273F,0xFF231F2F,0xFF1B1723,0xFF130F17,0xFF0B0707,
0xFF9BAB7B,0xFF8F9F6F,0xFF879763,0xFF7B8B57,0xFF73834B,0xFF677743,0xFF5F6F3B,0xFF576733,
0xFF4B5B27,0xFF3F4F1B,0xFF374313,0xFF2F3B0B,0xFF232F07,0xFF1B2300,0xFF131700,0xFF0B0F00,
0xFF00FF00,0xFF23E70F,0xFF3FD31B,0xFF53BB27,0xFF5FA72F,0xFF5F8F33,0xFF5F7B33,0xFFFFFFFF,
0xFFFFFFD3,0xFFFFFFA7,0xFFFFFF7F,0xFFFFFF53,0xFFFFFF27,0xFFFFEB1F,0xFFFFD717,0xFFFFBF0F,
0xFFFFAB07,0xFFFF9300,0xFFEF7F00,0xFFE36B00,0xFFD35700,0xFFC74700,0xFFB73B00,0xFFAB2B00,
0xFF9B1F00,0xFF8F1700,0xFF7F0F00,0xFF730700,0xFF5F0000,0xFF470000,0xFF2F0000,0xFF1B0000,
0xFFEF0000,0xFF3737FF,0xFFFF0000,0xFF0000FF,0xFF2B2B23,0xFF1B1B17,0xFF13130F,0xFFEB977F,
0xFFC37353,0xFF9F5733,0xFF7B3F1B,0xFFEBD3C7,0xFFC7AB9B,0xFFA78B77,0xFF876B57,0x009F5B53
};
#if 0
// palette halflife gfx/palette.lmp only 1 entry difference.. transparent = 0,0,255
static const u32 palette_lmp[256] = {
0xFF000000,0xFF0F0F0F,0xFF1F1F1F,0xFF2F2F2F,0xFF3F3F3F,0xFF4B4B4B,0xFF5B5B5B,0xFF6B6B6B,
0xFF7B7B7B,0xFF8B8B8B,0xFF9B9B9B,0xFFABABAB,0xFFBBBBBB,0xFFCBCBCB,0xFFDBDBDB,0xFFEBEBEB,
0xFF0F0B07,0xFF170F0B,0xFF1F170B,0xFF271B0F,0xFF2F2313,0xFF372B17,0xFF3F2F17,0xFF4B371B,
0xFF533B1B,0xFF5B431F,0xFF634B1F,0xFF6B531F,0xFF73571F,0xFF7B5F23,0xFF836723,0xFF8F6F23,
0xFF0B0B0F,0xFF13131B,0xFF1B1B27,0xFF272733,0xFF2F2F3F,0xFF37374B,0xFF3F3F57,0xFF474767,
0xFF4F4F73,0xFF5B5B7F,0xFF63638B,0xFF6B6B97,0xFF7373A3,0xFF7B7BAF,0xFF8383BB,0xFF8B8BCB,
0xFF000000,0xFF070700,0xFF0B0B00,0xFF131300,0xFF1B1B00,0xFF232300,0xFF2B2B07,0xFF2F2F07,
0xFF373707,0xFF3F3F07,0xFF474707,0xFF4B4B0B,0xFF53530B,0xFF5B5B0B,0xFF63630B,0xFF6B6B0F,
0xFF070000,0xFF0F0000,0xFF170000,0xFF1F0000,0xFF270000,0xFF2F0000,0xFF370000,0xFF3F0000,
0xFF470000,0xFF4F0000,0xFF570000,0xFF5F0000,0xFF670000,0xFF6F0000,0xFF770000,0xFF7F0000,
0xFF131300,0xFF1B1B00,0xFF232300,0xFF2F2B00,0xFF372F00,0xFF433700,0xFF4B3B07,0xFF574307,
0xFF5F4707,0xFF6B4B0B,0xFF77530F,0xFF835713,0xFF8B5B13,0xFF975F1B,0xFFA3631F,0xFFAF6723,
0xFF231307,0xFF2F170B,0xFF3B1F0F,0xFF4B2313,0xFF572B17,0xFF632F1F,0xFF733723,0xFF7F3B2B,
0xFF8F4333,0xFF9F4F33,0xFFAF632F,0xFFBF772F,0xFFCF8F2B,0xFFDFAB27,0xFFEFCB1F,0xFFFFF31B,
0xFF0B0700,0xFF1B1300,0xFF2B230F,0xFF372B13,0xFF47331B,0xFF533723,0xFF633F2B,0xFF6F4733,
0xFF7F533F,0xFF8B5F47,0xFF9B6B53,0xFFA77B5F,0xFFB7876B,0xFFC3937B,0xFFD3A38B,0xFFE3B397,
0xFFAB8BA3,0xFF9F7F97,0xFF937387,0xFF8B677B,0xFF7F5B6F,0xFF775363,0xFF6B4B57,0xFF5F3F4B,
0xFF573743,0xFF4B2F37,0xFF43272F,0xFF371F23,0xFF2B171B,0xFF231313,0xFF170B0B,0xFF0F0707,
0xFFBB739F,0xFFAF6B8F,0xFFA35F83,0xFF975777,0xFF8B4F6B,0xFF7F4B5F,0xFF734353,0xFF6B3B4B,
0xFF5F333F,0xFF532B37,0xFF47232B,0xFF3B1F23,0xFF2F171B,0xFF231313,0xFF170B0B,0xFF0F0707,
0xFFDBC3BB,0xFFCBB3A7,0xFFBFA39B,0xFFAF978B,0xFFA3877B,0xFF977B6F,0xFF876F5F,0xFF7B6353,
0xFF6B5747,0xFF5F4B3B,0xFF533F33,0xFF433327,0xFF372B1F,0xFF271F17,0xFF1B130F,0xFF0F0B07,
0xFF6F837B,0xFF677B6F,0xFF5F7367,0xFF576B5F,0xFF4F6357,0xFF475B4F,0xFF3F5347,0xFF374B3F,
0xFF2F4337,0xFF2B3B2F,0xFF233327,0xFF1F2B1F,0xFF172317,0xFF0F1B13,0xFF0B130B,0xFF070B07,
0xFFFFF31B,0xFFEFDF17,0xFFDBCB13,0xFFCBB70F,0xFFBBA70F,0xFFAB970B,0xFF9B8307,0xFF8B7307,
0xFF7B6307,0xFF6B5300,0xFF5B4700,0xFF4B3700,0xFF3B2B00,0xFF2B1F00,0xFF1B0F00,0xFF0B0700,
0xFF0000FF,0xFF0B0BEF,0xFF1313DF,0xFF1B1BCF,0xFF2323BF,0xFF2B2BAF,0xFF2F2F9F,0xFF2F2F8F,
0xFF2F2F7F,0xFF2F2F6F,0xFF2F2F5F,0xFF2B2B4F,0xFF23233F,0xFF1B1B2F,0xFF13131F,0xFF0B0B0F,
0xFF2B0000,0xFF3B0000,0xFF4B0700,0xFF5F0700,0xFF6F0F00,0xFF7F1707,0xFF931F07,0xFFA3270B,
0xFFB7330F,0xFFC34B1B,0xFFCF632B,0xFFDB7F3B,0xFFE3974F,0xFFE7AB5F,0xFFEFBF77,0xFFF7D38B,
0xFFA77B3B,0xFFB79B37,0xFFC7C337,0xFFE7E357,0xFF00FF00,0xFFABE7FF,0xFFD7FFFF,0xFF670000,
0xFF8B0000,0xFFB30000,0xFFD70000,0xFFFF0000,0xFFFFF393,0xFFFFF7C7,0xFFFFFFFF,0xFF9F5B53
};
#endif
bool CImageLoaderLMP::isALoadableFileExtension(const io::path& filename) const
{
return core::hasFileExtension ( filename, "lmp" );
}
bool CImageLoaderLMP::isALoadableFileFormat(irr::io::IReadFile* file) const
{
return false;
}
/*!
Quake1, Quake2, Hallife lmp texture
*/
IImage* CImageLoaderLMP::loadImage(irr::io::IReadFile* file) const
{
SLMPHeader header;
file->seek(0);
file->read(&header, sizeof(header));
// maybe palette file
u32 rawtexsize = header.width * header.height;
if ( rawtexsize + sizeof ( header ) != file->getSize() )
return 0;
u8 *rawtex = new u8 [ rawtexsize ];
file->read(rawtex, rawtexsize);
IImage* image = new CImage(ECF_A8R8G8B8, core::dimension2d<u32>(header.width, header.height));
CColorConverter::convert8BitTo32Bit(rawtex, (u8*)image->lock(), header.width, header.height, (u8*) colormap_h, 0, false);
image->unlock();
delete [] rawtex;
return image;
}
/*!
Halflife
*/
bool CImageLoaderWAL2::isALoadableFileExtension(const io::path& filename) const
{
// embedded in Wad(WAD3 format). originally it has no extension
return core::hasFileExtension ( filename, "wal2" );
}
bool CImageLoaderWAL2::isALoadableFileFormat(irr::io::IReadFile* file) const
{
return false;
}
/*
Halflite Texture WAD
*/
IImage* CImageLoaderWAL2::loadImage(irr::io::IReadFile* file) const
{
miptex_halflife header;
file->seek(0);
file->read(&header, sizeof(header));
#ifdef __BIG_ENDIAN__
header.width = os::Byteswap::byteswap(header.width);
header.height = os::Byteswap::byteswap(header.height);
#endif
// palette
//u32 paletteofs = header.mipmap[0] + ((rawtexsize * 85) >> 6) + 2;
u32 *pal = new u32 [ 192 + 256 ];
u8 *s = (u8*) pal;
file->seek ( file->getSize() - 768 - 2 );
file->read ( s, 768 );
u32 i;
for ( i = 0; i < 256; ++i, s+= 3 )
{
pal [ 192 + i ] = 0xFF000000 | s[0] << 16 | s[1] << 8 | s[2];
}
ECOLOR_FORMAT format = ECF_R8G8B8;
// transparency in filename;-) funny. rgb:0x0000FF is colorkey
if ( file->getFileName().findFirst ( '{' ) >= 0 )
{
format = ECF_A8R8G8B8;
pal [ 192 + 255 ] &= 0x00FFFFFF;
}
u32 rawtexsize = header.width * header.height;
u8 *rawtex = new u8 [ rawtexsize ];
file->seek ( header.mipmap[0] );
file->read(rawtex, rawtexsize);
IImage* image = new CImage(format, core::dimension2d<u32>(header.width, header.height));
switch ( format )
{
case ECF_R8G8B8:
CColorConverter::convert8BitTo24Bit(rawtex, (u8*)image->lock(), header.width, header.height, (u8*) pal + 768, 0, false);
break;
case ECF_A8R8G8B8:
CColorConverter::convert8BitTo32Bit(rawtex, (u8*)image->lock(), header.width, header.height, (u8*) pal + 768, 0, false);
break;
}
image->unlock();
delete [] rawtex;
delete [] pal;
return image;
}
bool CImageLoaderWAL::isALoadableFileExtension(const io::path& filename) const
{
return core::hasFileExtension ( filename, "wal" );
}
bool CImageLoaderWAL::isALoadableFileFormat(irr::io::IReadFile* file) const
{
return false;
}
/*!
quake2
*/
IImage* CImageLoaderWAL::loadImage(irr::io::IReadFile* file) const
{
miptex_quake2 header;
file->seek(0);
file->read(&header, sizeof(header));
#ifdef __BIG_ENDIAN__
header.width = os::Byteswap::byteswap(header.width);
header.height = os::Byteswap::byteswap(header.height);
#endif
u32 rawtexsize = header.width * header.height;
u8 *rawtex = new u8 [ rawtexsize ];
file->seek ( header.mipmap[0] );
file->read(rawtex, rawtexsize);
IImage* image = new CImage(ECF_A8R8G8B8, core::dimension2d<u32>(header.width, header.height));
CColorConverter::convert8BitTo32Bit(rawtex, (u8*)image->lock(), header.width, header.height, (u8*) colormap_pcx, 0, false);
image->unlock();
delete [] rawtex;
return image;
}
IImageLoader* createImageLoaderHalfLife()
{
return new irr::video::CImageLoaderWAL2();
}
IImageLoader* createImageLoaderWAL()
{
return new irr::video::CImageLoaderWAL();
}
IImageLoader* createImageLoaderLMP()
{
return new irr::video::CImageLoaderLMP();
}
}
}

View File

@ -17,6 +17,7 @@ namespace irr
{
namespace video
{
#if 0
#if defined(_MSC_VER) || defined(__BORLANDC__) || defined (__BCPLUSPLUS__)
# pragma pack( push, packing )
@ -62,6 +63,80 @@ private:
static s32 DefaultPaletteQ2[256];
};
#endif
//! An Irrlicht image loader for Quake1,2 engine lmp textures/palette
class CImageLoaderLMP : public irr::video::IImageLoader
{
public:
virtual bool isALoadableFileExtension(const io::path& filename) const;
virtual bool isALoadableFileFormat(irr::io::IReadFile* file) const;
virtual irr::video::IImage* loadImage(irr::io::IReadFile* file) const;
};
//! An Irrlicht image loader for quake2 wal engine textures
class CImageLoaderWAL : public irr::video::IImageLoader
{
public:
virtual bool isALoadableFileExtension(const io::path& filename) const;
virtual bool isALoadableFileFormat(irr::io::IReadFile* file) const;
virtual irr::video::IImage* loadImage(irr::io::IReadFile* file) const;
};
//! An Irrlicht image loader for Halife 1 engine textures
class CImageLoaderWAL2 : public irr::video::IImageLoader
{
public:
virtual bool isALoadableFileExtension(const io::path& filename) const;
virtual bool isALoadableFileFormat(irr::io::IReadFile* file) const;
virtual irr::video::IImage* loadImage(irr::io::IReadFile* file) const;
};
#if defined(_MSC_VER) || defined(__BORLANDC__) || defined (__BCPLUSPLUS__)
# pragma pack( push, packing )
# pragma pack( 1 )
# define PACK_STRUCT
#elif defined( __GNUC__ )
# define PACK_STRUCT __attribute__((packed))
#else
# error compiler not supported
#endif
struct SLMPHeader {
u32 width; // width
u32 height; // height
// variably sized
} PACK_STRUCT;
// Halfelife wad3 type 67 file
struct miptex_halflife
{
c8 name[16];
u32 width, height;
u32 mipmap[4]; // four mip maps stored
} PACK_STRUCT;
//quake2 texture
struct miptex_quake2
{
c8 name[32];
u32 width;
u32 height;
u32 mipmap[4]; // four mip maps stored
c8 animname[32]; // next frame in animation chain
s32 flags;
s32 contents;
s32 value;
};
#if defined(_MSC_VER) || defined(__BORLANDC__) || defined (__BCPLUSPLUS__)
# pragma pack( pop, packing )
#endif
#undef PACK_STRUCT
}
}

View File

@ -45,6 +45,12 @@ IImageLoader* createImageLoaderPNG();
//! creates a loader which is able to load WAL images
IImageLoader* createImageLoaderWAL();
//! creates a loader which is able to load halflife images
IImageLoader* createImageLoaderHalfLife();
//! creates a loader which is able to load lmp images
IImageLoader* createImageLoaderLMP();
//! creates a loader which is able to load ppm/pgm/pbm images
IImageLoader* createImageLoaderPPM();
@ -123,6 +129,13 @@ CNullDriver::CNullDriver(io::IFileSystem* io, const core::dimension2d<u32>& scre
#ifdef _IRR_COMPILE_WITH_WAL_LOADER_
SurfaceLoader.push_back(video::createImageLoaderWAL());
#endif
#ifdef _IRR_COMPILE_WITH_LMP_LOADER_
SurfaceLoader.push_back(video::createImageLoaderLMP());
#endif
#ifdef _IRR_COMPILE_WITH_HALFLIFE_LOADER_
SurfaceLoader.push_back(video::createImageLoaderHalfLife());
#endif
#ifdef _IRR_COMPILE_WITH_PPM_LOADER_
SurfaceLoader.push_back(video::createImageLoaderPPM());
#endif

View File

@ -29,6 +29,10 @@
#include "CMD2MeshFileLoader.h"
#endif
#ifdef _IRR_COMPILE_WITH_HALFLIFE_LOADER_
#include "CAnimatedMeshHalfLife.h"
#endif
#ifdef _IRR_COMPILE_WITH_MS3D_LOADER_
#include "CMS3DMeshFileLoader.h"
#endif
@ -222,6 +226,9 @@ CSceneManager::CSceneManager(video::IVideoDriver* driver, io::IFileSystem* fs,
#ifdef _IRR_COMPILE_WITH_MS3D_LOADER_
MeshLoaderList.push_back(new CMS3DMeshFileLoader(Driver));
#endif
#ifdef _IRR_COMPILE_WITH_HALFLIFE_LOADER_
MeshLoaderList.push_back(new CHalflifeMDLMeshFileLoader( this ));
#endif
#ifdef _IRR_COMPILE_WITH_3DS_LOADER_
MeshLoaderList.push_back(new C3DSMeshFileLoader(this, FileSystem));
#endif

View File

@ -331,8 +331,9 @@ void CShadowVolumeSceneNode::render()
driver->setTransform(video::ETS_WORLD, Parent->getAbsoluteTransformation());
for (u32 i=0; i<ShadowVolumesUsed; ++i)
driver->drawStencilShadowVolume(ShadowVolumes[i].pointer(),
ShadowVolumes[i].size(), UseZFailMethod);
{
driver->drawStencilShadowVolume(ShadowVolumes[i].pointer(),ShadowVolumes[i].size(), UseZFailMethod);
}
}

View File

@ -348,9 +348,12 @@ CBurningVideoDriver::CBurningVideoDriver(const irr::SIrrlichtCreationParameters&
BackBuffer->fill(SColor(0));
// create z buffer
DepthBuffer = video::createDepthBuffer(BackBuffer->getDimension());
if ( params.ZBufferBits )
DepthBuffer = video::createDepthBuffer(BackBuffer->getDimension());
// create stencil buffer
StencilBuffer = video::createStencilBuffer(BackBuffer->getDimension());
if ( params.Stencilbuffer )
StencilBuffer = video::createStencilBuffer(BackBuffer->getDimension());
}
// create triangle renderers
@ -607,6 +610,7 @@ bool CBurningVideoDriver::queryFeature(E_VIDEO_DRIVER_FEATURE feature) const
case EVDF_MIP_MAP:
return true;
#endif
case EVDF_STENCIL_BUFFER:
case EVDF_RENDER_TO_TARGET:
case EVDF_MULTITEXTURE:
case EVDF_HARDWARE_TL:

View File

@ -1395,6 +1395,14 @@
RelativePath="C3DSMeshFileLoader.h"
>
</File>
<File
RelativePath=".\CAnimatedMeshHalfLife.cpp"
>
</File>
<File
RelativePath=".\CAnimatedMeshHalfLife.h"
>
</File>
<File
RelativePath="CAnimatedMeshMD2.cpp"
>