diff --git a/lib/irrlicht/CMakeLists.txt b/lib/irrlicht/CMakeLists.txt index 3a49c3891..04c593a16 100644 --- a/lib/irrlicht/CMakeLists.txt +++ b/lib/irrlicht/CMakeLists.txt @@ -81,7 +81,6 @@ source/Irrlicht/CNPKReader.cpp source/Irrlicht/CIrrMeshFileLoader.cpp source/Irrlicht/COpenGLSLMaterialRenderer.cpp source/Irrlicht/CParticleRotationAffector.cpp -source/Irrlicht/CAnimatedMeshHalfLife.cpp source/Irrlicht/CDepthBuffer.cpp source/Irrlicht/CImageLoaderPSD.cpp source/Irrlicht/CTriangleBBSelector.cpp @@ -232,7 +231,6 @@ source/Irrlicht/COpenGLTexture.h source/Irrlicht/Octree.h source/Irrlicht/os.h source/Irrlicht/CDefaultGUIElementFactory.h -source/Irrlicht/CAnimatedMeshHalfLife.h source/Irrlicht/CSceneNodeAnimatorFlyCircle.h source/Irrlicht/CBSPMeshFileLoader.h source/Irrlicht/CTriangleBBSelector.h diff --git a/lib/irrlicht/include/IrrCompileConfig.h b/lib/irrlicht/include/IrrCompileConfig.h index a09ab6c33..8a4e60a40 100644 --- a/lib/irrlicht/include/IrrCompileConfig.h +++ b/lib/irrlicht/include/IrrCompileConfig.h @@ -327,11 +327,6 @@ B3D, MS3D or X meshes */ #ifdef NO_IRR_COMPILE_WITH_IRR_MESH_LOADER_ #undef _IRR_COMPILE_WITH_IRR_MESH_LOADER_ #endif -//! Define _IRR_COMPILE_WITH_HALFLIFE_LOADER_ if you want to load Halflife animated files -#define _IRR_COMPILE_WITH_HALFLIFE_LOADER_ -#ifdef NO_IRR_COMPILE_WITH_HALFLIFE_LOADER_ -#undef _IRR_COMPILE_WITH_HALFLIFE_LOADER_ -#endif //! Define _IRR_COMPILE_WITH_MD2_LOADER_ if you want to load Quake 2 animated files #define _IRR_COMPILE_WITH_MD2_LOADER_ #ifdef NO_IRR_COMPILE_WITH_MD2_LOADER_ diff --git a/lib/irrlicht/source/Irrlicht/CAnimatedMeshHalfLife.cpp b/lib/irrlicht/source/Irrlicht/CAnimatedMeshHalfLife.cpp deleted file mode 100644 index 6531e1a6e..000000000 --- a/lib/irrlicht/source/Irrlicht/CAnimatedMeshHalfLife.cpp +++ /dev/null @@ -1,1695 +0,0 @@ -// Copyright (C) 2002-2012 Nikolaus Gebhardt / Fabio Concas / Thomas Alten -// 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_HALFLIFE_LOADER_ - -#include "CAnimatedMeshHalfLife.h" -#include "os.h" -#include "CColorConverter.h" -#include "CImage.h" -#include "coreutil.h" -#include "SMeshBuffer.h" -#include "IVideoDriver.h" -#include "IFileSystem.h" - -namespace irr -{ -namespace scene -{ - - using namespace video; - - void AngleQuaternion(const core::vector3df& angles, vec4_hl quaternion) - { - f32 angle; - f32 sr, sp, sy, cr, cp, cy; - - // FIXME: rescale the inputs to 1/2 angle - angle = angles.Z * 0.5f; - sy = sin(angle); - cy = cos(angle); - angle = angles.Y * 0.5f; - sp = sin(angle); - cp = cos(angle); - angle = angles.X * 0.5f; - sr = sin(angle); - cr = cos(angle); - - quaternion[0] = sr*cp*cy-cr*sp*sy; // X - quaternion[1] = cr*sp*cy+sr*cp*sy; // Y - quaternion[2] = cr*cp*sy-sr*sp*cy; // Z - quaternion[3] = cr*cp*cy+sr*sp*sy; // W - } - - void QuaternionMatrix( const vec4_hl quaternion, f32 (*matrix)[4] ) - { - matrix[0][0] = 1.f - 2.f * quaternion[1] * quaternion[1] - 2.f * quaternion[2] * quaternion[2]; - matrix[1][0] = 2.f * quaternion[0] * quaternion[1] + 2.f * quaternion[3] * quaternion[2]; - matrix[2][0] = 2.f * quaternion[0] * quaternion[2] - 2.f * quaternion[3] * quaternion[1]; - - matrix[0][1] = 2.f * quaternion[0] * quaternion[1] - 2.f * quaternion[3] * quaternion[2]; - matrix[1][1] = 1.f - 2.f * quaternion[0] * quaternion[0] - 2.f * quaternion[2] * quaternion[2]; - matrix[2][1] = 2.f * quaternion[1] * quaternion[2] + 2.f * quaternion[3] * quaternion[0]; - - matrix[0][2] = 2.f * quaternion[0] * quaternion[2] + 2.f * quaternion[3] * quaternion[1]; - matrix[1][2] = 2.f * quaternion[1] * quaternion[2] - 2.f * quaternion[3] * quaternion[0]; - matrix[2][2] = 1.f - 2.f * quaternion[0] * quaternion[0] - 2.f * quaternion[1] * quaternion[1]; - } - - void QuaternionSlerp( const vec4_hl p, vec4_hl q, f32 t, vec4_hl qt ) - { - s32 i; - f32 omega, cosom, sinom, sclp, sclq; - - // decide if one of the quaternions is backwards - f32 a = 0; - f32 b = 0; - for (i = 0; i < 4; i++) { - a += (p[i]-q[i])*(p[i]-q[i]); - b += (p[i]+q[i])*(p[i]+q[i]); - } - if (a > b) { - for (i = 0; i < 4; i++) { - q[i] = -q[i]; - } - } - - cosom = p[0]*q[0] + p[1]*q[1] + p[2]*q[2] + p[3]*q[3]; - - if ((1.f + cosom) > 0.00000001) { - if ((1.f - cosom) > 0.00000001) { - omega = acos( cosom ); - sinom = sin( omega ); - sclp = sin( (1.f - t)*omega) / sinom; - sclq = sin( t*omega ) / sinom; - } - else { - sclp = 1.f - t; - sclq = t; - } - for (i = 0; i < 4; i++) { - qt[i] = sclp * p[i] + sclq * q[i]; - } - } - else { - qt[0] = -p[1]; - qt[1] = p[0]; - qt[2] = -p[3]; - qt[3] = p[2]; - sclp = sin( (1.f - t) * 0.5f * core::PI); - sclq = sin( t * 0.5f * core::PI); - for (i = 0; i < 3; i++) { - qt[i] = sclp * p[i] + sclq * qt[i]; - } - } - } - - void R_ConcatTransforms (const f32 in1[3][4], const f32 in2[3][4], f32 out[3][4]) - { - out[0][0] = in1[0][0] * in2[0][0] + in1[0][1] * in2[1][0] + in1[0][2] * in2[2][0]; - out[0][1] = in1[0][0] * in2[0][1] + in1[0][1] * in2[1][1] + in1[0][2] * in2[2][1]; - out[0][2] = in1[0][0] * in2[0][2] + in1[0][1] * in2[1][2] + in1[0][2] * in2[2][2]; - out[0][3] = in1[0][0] * in2[0][3] + in1[0][1] * in2[1][3] + in1[0][2] * in2[2][3] + in1[0][3]; - out[1][0] = in1[1][0] * in2[0][0] + in1[1][1] * in2[1][0] + in1[1][2] * in2[2][0]; - out[1][1] = in1[1][0] * in2[0][1] + in1[1][1] * in2[1][1] + in1[1][2] * in2[2][1]; - out[1][2] = in1[1][0] * in2[0][2] + in1[1][1] * in2[1][2] + in1[1][2] * in2[2][2]; - out[1][3] = in1[1][0] * in2[0][3] + in1[1][1] * in2[1][3] + in1[1][2] * in2[2][3] + in1[1][3]; - out[2][0] = in1[2][0] * in2[0][0] + in1[2][1] * in2[1][0] + in1[2][2] * in2[2][0]; - out[2][1] = in1[2][0] * in2[0][1] + in1[2][1] * in2[1][1] + in1[2][2] * in2[2][1]; - out[2][2] = in1[2][0] * in2[0][2] + in1[2][1] * in2[1][2] + in1[2][2] * in2[2][2]; - out[2][3] = in1[2][0] * in2[0][3] + in1[2][1] * in2[1][3] + in1[2][2] * in2[2][3] + in1[2][3]; - } - - #define DotProduct(x,y) ((x)[0]*(y)[0]+(x)[1]*(y)[1]+(x)[2]*(y)[2]) - - inline void VectorTransform(const vec3_hl in1, const f32 in2[3][4], core::vector3df& out) - { - out.X = DotProduct(in1, in2[0]) + in2[0][3]; - out.Z = DotProduct(in1, in2[1]) + in2[1][3]; - out.Y = DotProduct(in1, in2[2]) + in2[2][3]; - } - - static f32 BoneTransform[MAXSTUDIOBONES][3][4]; // bone transformation matrix - - void getBoneVector ( core::vector3df &out, u32 index ) - { - out.X = BoneTransform[index][0][3]; - out.Z = BoneTransform[index][1][3]; - out.Y = BoneTransform[index][2][3]; - } - - void getBoneBox ( core::aabbox3df &box, u32 index, f32 size = 0.5f ) - { - box.MinEdge.X = BoneTransform[index][0][3] - size; - box.MinEdge.Z = BoneTransform[index][1][3] - size; - box.MinEdge.Y = BoneTransform[index][2][3] - size; - - size *= 2.f; - box.MaxEdge.X = box.MinEdge.X + size; - box.MaxEdge.Y = box.MinEdge.Y + size; - box.MaxEdge.Z = box.MinEdge.Z + size; - } - - void getTransformedBoneVector ( core::vector3df &out, u32 index, const vec3_hl in) - { - out.X = DotProduct(in, BoneTransform[index][0]) + BoneTransform[index][0][3]; - out.Z = DotProduct(in, BoneTransform[index][1]) + BoneTransform[index][1][3]; - out.Y = DotProduct(in, BoneTransform[index][2]) + BoneTransform[index][2][3]; - - } - - -//! Constructor -CHalflifeMDLMeshFileLoader::CHalflifeMDLMeshFileLoader( - scene::ISceneManager* smgr) : SceneManager(smgr) -{ -#ifdef _DEBUG - setDebugName("CHalflifeMDLMeshFileLoader"); -#endif -} - - -//! returns true if the file maybe is able to be loaded by this class -//! based on the file extension (e.g. ".bsp") -bool CHalflifeMDLMeshFileLoader::isALoadableFileExtension(const io::path& filename) const -{ - return core::hasFileExtension(filename, "mdl"); -} - - -//! 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. -IAnimatedMesh* CHalflifeMDLMeshFileLoader::createMesh(io::IReadFile* file) -{ - CAnimatedMeshHalfLife* msh = new CAnimatedMeshHalfLife(); - if (msh) - { - if (msh->loadModelFile(file, SceneManager)) - return msh; - msh->drop(); - } - - return 0; -} - - -//! Constructor -CAnimatedMeshHalfLife::CAnimatedMeshHalfLife() - : FrameCount(0), MeshIPol(0), SceneManager(0), Header(0), TextureHeader(0), - OwnTexModel(false), SequenceIndex(0), CurrentFrame(0), FramesPerSecond(25.f), - SkinGroupSelection(0) -#ifdef HL_TEXTURE_ATLAS - , TextureMaster(0) -#endif -{ -#ifdef _DEBUG - setDebugName("CAnimatedMeshHalfLife"); -#endif - initData(); -} - -/*! - loads a complete model -*/ -bool CAnimatedMeshHalfLife::loadModelFile(io::IReadFile* file, - ISceneManager* smgr) -{ - if (!file) - return false; - - SceneManager = smgr; - - if ( loadModel(file, file->getFileName()) ) - { - if ( postLoadModel ( file->getFileName() ) ) - { - initModel (); - //dumpModelInfo ( 1 ); - return true; - } - } - return false; -} - - -//! Destructor -CAnimatedMeshHalfLife::~CAnimatedMeshHalfLife() -{ - delete [] (u8*) Header; - if (OwnTexModel) - delete [] (u8*) TextureHeader; - - for (u32 i = 0; i < 32; ++i) - delete [] (u8*) AnimationHeader[i]; - - if (MeshIPol) - MeshIPol->drop(); -} - - -//! Returns the amount of frames in milliseconds. If the amount is 1, it is a static (=non animated) mesh. -u32 CAnimatedMeshHalfLife::getFrameCount() const -{ - return FrameCount; -} - - -//! set the hardware mapping hint, for driver -void CAnimatedMeshHalfLife::setHardwareMappingHint(E_HARDWARE_MAPPING newMappingHint,E_BUFFER_TYPE buffer) -{ -} - - -//! flags the meshbuffer as changed, reloads hardware buffers -void CAnimatedMeshHalfLife::setDirty(E_BUFFER_TYPE buffer) -{ -} - - -static core::vector3df TransformedVerts[MAXSTUDIOVERTS]; // transformed vertices -//static core::vector3df TransformedNormals[MAXSTUDIOVERTS]; // light surface normals - - -/*! -*/ -void CAnimatedMeshHalfLife::initModel() -{ - // init Sequences to Animation - KeyFrameInterpolation ipol; - ipol.Name.reserve ( 64 ); - u32 i; - - AnimList.clear(); - FrameCount = 0; - - SHalflifeSequence *seq = (SHalflifeSequence*) ((u8*) Header + Header->seqindex); - for ( i = 0; i < Header->numseq; i++) - { - ipol.Name = seq[i].label; - ipol.StartFrame = FrameCount; - ipol.Frames = core::max_ ( 1, seq[i].numframes - 1 ); - ipol.EndFrame = ipol.StartFrame + ipol.Frames - 1; - ipol.FramesPerSecond = seq[i].fps; - ipol.AnimationType = seq[i].flags & STUDIO_LOOPING ? EAMT_LOOPING : EAMT_WAYPOINT; - AnimList.push_back ( ipol ); - - FrameCount += ipol.Frames; - } - - // initBoneControllers -/* - SHalflifeBoneController *bonecontroller = (SHalflifeBoneController *)((u8*) Header + Header->bonecontrollerindex); - for ( i = 0; i < Header->numbonecontrollers; i++) - { - printf ( "BoneController%d index:%d%s range:%f - %f\n", - i, - bonecontroller[i].index, bonecontroller[i].index == MOUTH_CONTROLLER ? " (Mouth)": "", - bonecontroller[i].start,bonecontroller[i].end - ); - } - - // initSkins - for (i = 0; i < TextureHeader->numskinfamilies; i++) - { - printf ( "Skin%d\n", i + 1); - } -*/ - - // initBodyparts - u32 meshBuffer = 0; - BodyList.clear(); - SHalflifeBody *body = (SHalflifeBody *) ((u8*) Header + Header->bodypartindex); - for (i=0; i < Header->numbodyparts; ++i) - { - BodyPart part; - part.name = body[i].name; - part.defaultModel = core::max_ ( 0, (s32) body[i].base - 1 ); - - SHalflifeModel * model = (SHalflifeModel *)((u8*) Header + body[i].modelindex); - for ( u32 g = 0; g < body[i].nummodels; ++g) - { - SubModel sub; - sub.name = model[g].name; - sub.startBuffer = meshBuffer; - sub.endBuffer = sub.startBuffer + model[g].nummesh; - sub.state = g == part.defaultModel; - part.model.push_back ( sub ); - meshBuffer += model[g].nummesh; - } - BodyList.push_back ( part ); - } - - SequenceIndex = 0; - CurrentFrame = 0.f; - - SetController(0, 0.f); - SetController(1, 0.f); - SetController(2, 0.f); - SetController(3, 0.f); - SetController(MOUTH_CONTROLLER, 0.f); - - SetSkin (0); - - // init Meshbuffers - const SHalflifeTexture *tex = (SHalflifeTexture *) ((u8*) TextureHeader + TextureHeader->textureindex); - const u16 *skinref = (u16 *)((u8*)TextureHeader + TextureHeader->skinindex); - if ((SkinGroupSelection != 0) && (SkinGroupSelection < TextureHeader->numskinfamilies)) - skinref += (SkinGroupSelection * TextureHeader->numskinref); - - core::vector2df tex_scale; - core::vector2di tex_trans ( 0, 0 ); - -#ifdef HL_TEXTURE_ATLAS - TextureAtlas.getScale(tex_scale); -#endif - - for (u32 bodypart=0 ; bodypart < Header->numbodyparts ; ++bodypart) - { - const SHalflifeBody *body = (SHalflifeBody *)((u8*) Header + Header->bodypartindex) + bodypart; - - for (u32 modelnr = 0; modelnr < body->nummodels; ++modelnr) - { - const SHalflifeModel *model = (SHalflifeModel *)((u8*) Header + body->modelindex) + modelnr; -#if 0 - const vec3_hl *studioverts = (vec3_hl *)((u8*)Header + model->vertindex); - const vec3_hl *studionorms = (vec3_hl *)((u8*)Header + model->normindex); -#endif - for (i = 0; i < model->nummesh; ++i) - { - const SHalflifeMesh *mesh = (SHalflifeMesh *)((u8*)Header + model->meshindex) + i; - const SHalflifeTexture *currentex = &tex[skinref[mesh->skinref]]; - -#ifdef HL_TEXTURE_ATLAS - TextureAtlas.getTranslation ( currentex->name, tex_trans ); -#else - tex_scale.X = 1.f/(f32)currentex->width; - tex_scale.Y = 1.f/(f32)currentex->height; -#endif - - SMeshBuffer * buffer = new SMeshBuffer(); - - // count index vertex size indexcount = mesh->numtris * 3 - u32 indexCount = 0; - u32 vertexCount = 0; - - const s16 *tricmd = (s16*)((u8*)Header + mesh->triindex); - s32 c; - while ( (c = *(tricmd++)) ) - { - if (c < 0) - c = -c; - - indexCount += ( c - 2 ) * 3; - vertexCount += c; - tricmd += ( 4 * c ); - } - - // indices - buffer->Indices.set_used ( indexCount ); - buffer->Vertices.set_used ( vertexCount ); - - // fill in static indices and vertex - u16 *index = buffer->Indices.pointer(); - video::S3DVertex * v = buffer->Vertices.pointer(); - - // blow up gl_triangle_fan/gl_triangle_strip to indexed triangle list - E_PRIMITIVE_TYPE type; - vertexCount = 0; - indexCount = 0; - tricmd = (s16*)((u8*)Header + mesh->triindex); - while ( (c = *(tricmd++)) ) - { - if (c < 0) - { - // triangle fan - c = -c; - type = EPT_TRIANGLE_FAN; - } - else - { - type = EPT_TRIANGLE_STRIP; - } - - for ( s32 g = 0; g < c; ++g, v += 1, tricmd += 4 ) - { - // fill vertex - #if 0 - const f32 *av = studioverts[tricmd[0]]; - v->Pos.X = av[0]; - v->Pos.Z = av[1]; - v->Pos.Y = av[2]; - - av = studionorms[tricmd[1]]; - v->Normal.X = av[0]; - v->Normal.Z = av[1]; - v->Normal.Y = av[2]; - - #endif - v->Normal.X = 0.f; - v->Normal.Z = 0.f; - v->Normal.Y = 1.f; - - v->TCoords.X = (tex_trans.X + tricmd[2])*tex_scale.X; - v->TCoords.Y = (tex_trans.Y + tricmd[3])*tex_scale.Y; - - v->Color.color = 0xFFFFFFFF; - - // fill index - if ( g < c - 2 ) - { - if ( type == EPT_TRIANGLE_FAN ) - { - index[indexCount+0] = vertexCount; - index[indexCount+1] = vertexCount+g+1; - index[indexCount+2] = vertexCount+g+2; - } - else - { - if ( g & 1 ) - { - index[indexCount+0] = vertexCount+g+1; - index[indexCount+1] = vertexCount+g+0; - index[indexCount+2] = vertexCount+g+2; - } - else - { - index[indexCount+0] = vertexCount+g+0; - index[indexCount+1] = vertexCount+g+1; - index[indexCount+2] = vertexCount+g+2; - } - } - - indexCount += 3; - } - } - - vertexCount += c; - } - - // material - video::SMaterial &m = buffer->getMaterial(); - - m.MaterialType = video::EMT_SOLID; - m.BackfaceCulling = true; - - if ( currentex->flags & STUDIO_NF_CHROME ) - { - // don't know what to do with chrome here - } - -#ifdef HL_TEXTURE_ATLAS - io::path store = TextureBaseName + "atlas"; -#else - io::path fname; - io::path ext; - core::splitFilename ( currentex->name, 0, &fname, &ext ); - io::path store = TextureBaseName + fname; -#endif - m.TextureLayer[0].Texture = SceneManager->getVideoDriver()->getTexture ( store ); - m.Lighting = false; - - MeshIPol->addMeshBuffer(buffer); - buffer->recalculateBoundingBox(); - buffer->drop(); - } // mesh - MeshIPol->recalculateBoundingBox(); - } // model - } // body part -} - - -/*! -*/ -void CAnimatedMeshHalfLife::buildVertices() -{ -/* - const u16 *skinref = (u16 *)((u8*)TextureHeader + TextureHeader->skinindex); - if (SkinGroupSelection != 0 && SkinGroupSelection < TextureHeader->numskinfamilies) - skinref += (SkinGroupSelection * TextureHeader->numskinref); -*/ - u32 i; - s32 c,g; - const s16 *tricmd; - - u32 meshBufferNr = 0; - for ( u32 bodypart = 0 ; bodypart < Header->numbodyparts; ++bodypart) - { - const SHalflifeBody *body = (SHalflifeBody *)((u8*) Header + Header->bodypartindex) + bodypart; - - for ( u32 modelnr = 0; modelnr < body->nummodels; ++modelnr ) - { - const SHalflifeModel *model = (SHalflifeModel *)((u8*) Header + body->modelindex) + modelnr; - - const u8 *vertbone = ((u8*)Header + model->vertinfoindex); - - const vec3_hl *studioverts = (vec3_hl *)((u8*)Header + model->vertindex); - - for ( i = 0; i < model->numverts; i++) - { - VectorTransform ( studioverts[i], BoneTransform[vertbone[i]], TransformedVerts[i] ); - } - /* - const u8 *normbone = ((u8*)Header + model->norminfoindex); - const vec3_hl *studionorms = (vec3_hl *)((u8*)Header + model->normindex); - for ( i = 0; i < model->numnorms; i++) - { - VectorTransform ( studionorms[i], BoneTransform[normbone[i]], TransformedNormals[i] ); - } - */ - for (i = 0; i < model->nummesh; i++) - { - const SHalflifeMesh *mesh = (SHalflifeMesh *)((u8*)Header + model->meshindex) + i; - - IMeshBuffer * buffer = MeshIPol->getMeshBuffer ( meshBufferNr++ ); - video::S3DVertex* v = (video::S3DVertex* ) buffer->getVertices(); - - tricmd = (s16*)((u8*)Header + mesh->triindex); - while ( (c = *(tricmd++)) ) - { - if (c < 0) - c = -c; - - for ( g = 0; g < c; ++g, v += 1, tricmd += 4 ) - { - // fill vertex - const core::vector3df& av = TransformedVerts[tricmd[0]]; - v->Pos = av; - /* - const core::vector3df& an = TransformedNormals[tricmd[1]]; - v->Normal = an; - //v->Normal.normalize(); - */ - } - } // tricmd - } // nummesh - } // model - } // bodypart -} - - -/*! - render Bones -*/ -void CAnimatedMeshHalfLife::renderModel(u32 param, IVideoDriver * driver, const core::matrix4 &absoluteTransformation) -{ - SHalflifeBone *bone = (SHalflifeBone *) ((u8 *) Header + Header->boneindex); - - video::SColor blue(0xFF000080); - video::SColor red(0xFF800000); - video::SColor yellow(0xFF808000); - video::SColor cyan(0xFF008080); - - core::aabbox3df box; - - u32 i; - for ( i = 0; i < Header->numbones; i++) - { - if (bone[i].parent >= 0) - { - getBoneVector ( box.MinEdge, bone[i].parent ); - getBoneVector ( box.MaxEdge, i ); - driver->draw3DLine ( box.MinEdge, box.MaxEdge, blue ); - - // draw parent bone node - if (bone[bone[i].parent].parent >=0 ) - { - getBoneBox ( box, bone[i].parent ); - driver->draw3DBox ( box, blue ); - } - getBoneBox ( box, i ); - driver->draw3DBox ( box, blue ); - } - else - { - // draw parent bone node - getBoneBox ( box, i, 1.f ); - driver->draw3DBox ( box , red ); - } - } - - // attachements - SHalflifeAttachment *attach = (SHalflifeAttachment *) ((u8*) Header + Header->attachmentindex); - core::vector3df v[8]; - for ( i = 0; i < Header->numattachments; i++) - { - getTransformedBoneVector ( v[0],attach[i].bone,attach[i].org ); - getTransformedBoneVector ( v[1],attach[i].bone,attach[i].vectors[0] ); - getTransformedBoneVector ( v[2],attach[i].bone,attach[i].vectors[1] ); - getTransformedBoneVector ( v[3],attach[i].bone,attach[i].vectors[2] ); - driver->draw3DLine ( v[0], v[1], cyan ); - driver->draw3DLine ( v[0], v[2], cyan ); - driver->draw3DLine ( v[0], v[3], cyan ); - } - - // hit boxes - SHalflifeBBox *hitbox = (SHalflifeBBox *) ((u8*) Header + Header->hitboxindex); - f32 *bbmin,*bbmax; - vec3_hl v2[8]; - for (i = 0; i < Header->numhitboxes; i++) - { - bbmin = hitbox[i].bbmin; - bbmax = hitbox[i].bbmax; - - v2[0][0] = bbmin[0]; - v2[0][1] = bbmax[1]; - v2[0][2] = bbmin[2]; - - v2[1][0] = bbmin[0]; - v2[1][1] = bbmin[1]; - v2[1][2] = bbmin[2]; - - v2[2][0] = bbmax[0]; - v2[2][1] = bbmax[1]; - v2[2][2] = bbmin[2]; - - v2[3][0] = bbmax[0]; - v2[3][1] = bbmin[1]; - v2[3][2] = bbmin[2]; - - v2[4][0] = bbmax[0]; - v2[4][1] = bbmax[1]; - v2[4][2] = bbmax[2]; - - v2[5][0] = bbmax[0]; - v2[5][1] = bbmin[1]; - v2[5][2] = bbmax[2]; - - v2[6][0] = bbmin[0]; - v2[6][1] = bbmax[1]; - v2[6][2] = bbmax[2]; - - v2[7][0] = bbmin[0]; - v2[7][1] = bbmin[1]; - v2[7][2] = bbmax[2]; - - for ( u32 g = 0; g < 8; ++g ) - getTransformedBoneVector ( v[g],hitbox[i].bone,v2[g] ); - - driver->draw3DLine(v[0], v[1], yellow); - driver->draw3DLine(v[1], v[3], yellow); - driver->draw3DLine(v[3], v[2], yellow); - driver->draw3DLine(v[2], v[0], yellow); - - driver->draw3DLine(v[4], v[5], yellow); - driver->draw3DLine(v[5], v[7], yellow); - driver->draw3DLine(v[7], v[6], yellow); - driver->draw3DLine(v[6], v[4], yellow); - - driver->draw3DLine(v[0], v[6], yellow); - driver->draw3DLine(v[1], v[7], yellow); - driver->draw3DLine(v[3], v[5], yellow); - driver->draw3DLine(v[2], v[4], yellow); - } -} - - -//! Returns the animated mesh based on a detail level. 0 is the lowest, 255 the highest detail. -IMesh* CAnimatedMeshHalfLife::getMesh(s32 frameInt, s32 detailLevel, s32 startFrameLoop, s32 endFrameLoop) -{ - f32 frame = frameInt + (detailLevel * 0.001f); - u32 frameA = core::floor32 ( frame ); -// f32 blend = core::fract ( frame ); - - SHalflifeSequence *seq = (SHalflifeSequence*) ((u8*) Header + Header->seqindex); - - // find SequenceIndex from summed list - u32 frameCount = 0; - for (u32 i = 0; i < Header->numseq; ++i) - { - u32 val = core::max_ ( 1, seq[i].numframes - 1 ); - if ( frameCount + val > frameA ) - { - SequenceIndex = i; - CurrentFrame = frame - frameCount; - break; - } - frameCount += val; - } - - seq += SequenceIndex; - - //SetBodyPart ( 1, 1 ); - setUpBones (); - buildVertices(); - - MeshIPol->BoundingBox.MinEdge.X = seq->bbmin[0]; - MeshIPol->BoundingBox.MinEdge.Z = seq->bbmin[1]; - MeshIPol->BoundingBox.MinEdge.Y = seq->bbmin[2]; - - MeshIPol->BoundingBox.MaxEdge.X = seq->bbmax[0]; - MeshIPol->BoundingBox.MaxEdge.Z = seq->bbmax[1]; - MeshIPol->BoundingBox.MaxEdge.Y = seq->bbmax[2]; - - return MeshIPol; -} - - -/*! -*/ -void CAnimatedMeshHalfLife::initData () -{ - u32 i; - - Header = 0; - TextureHeader = 0; - OwnTexModel = false; - - for ( i = 0; i < 32; ++i ) - AnimationHeader[i] = 0; - - SequenceIndex = 0; - CurrentFrame = 0.f; - - for ( i = 0; i < 5; ++i ) - BoneController[i] = 0; - - for ( i = 0; i < 2; ++i ) - Blending[i] = 0; - - SkinGroupSelection = 0; - - AnimList.clear(); - FrameCount = 0; - - if (!MeshIPol) - MeshIPol = new SMesh(); - MeshIPol->clear(); - -#ifdef HL_TEXTURE_ATLAS - TextureAtlas.release(); -#endif -} - - -/*! -*/ -void STextureAtlas::release() -{ - for (u32 i = 0; i < atlas.size(); i++) - { - if ( atlas[i].image ) - { - atlas[i].image->drop(); - atlas[i].image = 0; - } - } - Master = 0; -} - - -/*! -*/ -void STextureAtlas::addSource ( const c8 * name, video::IImage * image ) -{ - TextureAtlasEntry entry; - entry.name = name; - entry.image = image; - entry.width = image->getDimension().Width; - entry.height = image->getDimension().Height; - entry.pos.X = 0; - entry.pos.Y = 0; - atlas.push_back ( entry ); -} - - -/*! -*/ -void STextureAtlas::getScale(core::vector2df& scale) -{ - for (s32 i = static_cast(atlas.size()) - 1; i >= 0; --i) - { - if ( atlas[i].name == "_merged_" ) - { - scale.X = 1.f / atlas[i].width; - scale.Y = 1.f / atlas[i].height; - return; - } - } - scale.X = 1.f; - scale.Y = 1.f; -} - - -/*! -*/ -void STextureAtlas::getTranslation(const c8* name, core::vector2di& pos) -{ - for ( u32 i = 0; i < atlas.size(); ++i) - { - if ( atlas[i].name == name ) - { - pos = atlas[i].pos; - return; - } - } -} - - -/*! -*/ -void STextureAtlas::create(u32 border, E_TEXTURE_CLAMP texmode) -{ - u32 i = 0; - u32 w = 0; - u32 w2; - u32 h2; - u32 h; - u32 wsum; - u32 hsum = 0; - ECOLOR_FORMAT format = ECF_R8G8B8; - - const s32 frame = core::s32_max ( 0, (border - 1 ) / 2 ); - - // sort for biggest coming first - atlas.sort(); - - // split size - wsum = frame; - for (i = 0; i < atlas.size(); i++) - { - // make space - w2 = atlas[i].width + border; - - // align - w2 = (w2 + 1) & ~1; - wsum += w2; - } - u32 splitsize = 256; - if ( wsum > 512 ) - splitsize = 512; - - wsum = frame; - hsum = frame; - w = frame; - h = 0; - for (i = 0; i < atlas.size(); i++) - { - if ( atlas[i].image->getColorFormat() == ECF_A8R8G8B8 ) - { - format = ECF_A8R8G8B8; - } - - // make space - w2 = atlas[i].width + border; - h2 = atlas[i].height + border; - - // align - w2 = (w2 + 1) & ~1; - h2 = (h2 + 1) & ~1; - - h = core::s32_max ( h, h2 ); - - if ( w + w2 >= splitsize ) - { - hsum += h; - wsum = core::s32_max ( wsum, w ); - h = h2; - w = frame; - } - - atlas[i].pos.X = w; - atlas[i].pos.Y = hsum; - - w += w2; - - } - hsum += h; - wsum = core::s32_max ( wsum, w ); - - // build image - core::dimension2d dim = core::dimension2d( wsum, hsum ).getOptimalSize(); - IImage* master = new CImage(format, dim); - master->fill(0); - - video::SColor col[2]; - - static const u8 wrap[][4] = - { - {1, 0}, // ETC_REPEAT - {0, 1}, // ETC_CLAMP - {0, 1}, // ETC_CLAMP_TO_EDGE - {0, 1} // ETC_MIRROR - }; - - s32 a,b; - for (i = 0; i < atlas.size(); i++) - { - atlas[i].image->copyTo ( master, atlas[i].pos ); - - // clamp/wrap ( copy edges, filtering needs it ) - - for ( b = 0; b < frame; ++b ) - { - for ( a = 0 - b; a <= (s32) atlas[i].width + b; ++a ) - { - col[0] = atlas[i].image->getPixel ( core::s32_clamp ( a, 0, atlas[i].width - 1 ), 0 ); - col[1] = atlas[i].image->getPixel ( core::s32_clamp ( a, 0, atlas[i].width - 1 ), atlas[i].height - 1 ); - - master->setPixel ( atlas[i].pos.X + a, atlas[i].pos.Y + ( b + 1 ) * -1, col[wrap[texmode][0]] ); - master->setPixel ( atlas[i].pos.X + a, atlas[i].pos.Y + atlas[i].height - 1 + ( b + 1 ) * 1, col[wrap[texmode][1]] ); - } - - for ( a = -1 - b; a <= (s32) atlas[i].height + b; ++a ) - { - col[0] = atlas[i].image->getPixel ( 0, core::s32_clamp ( a, 0, atlas[i].height - 1 ) ); - col[1] = atlas[i].image->getPixel ( atlas[i].width - 1, core::s32_clamp ( a, 0, atlas[i].height - 1 ) ); - - master->setPixel ( atlas[i].pos.X + ( b + 1 ) * -1, atlas[i].pos.Y + a, col[wrap[texmode][0]] ); - master->setPixel ( atlas[i].pos.X + atlas[i].width + b, atlas[i].pos.Y + a, col[wrap[texmode][1]] ); - } - } - } - - addSource ( "_merged_", master ); - Master = master; -} - - -/*! -*/ -SHalflifeHeader* CAnimatedMeshHalfLife::loadModel(io::IReadFile* file, const io::path& filename) -{ - bool closefile = false; - - // if secondary files are needed, open here and mark for closing - if ( 0 == file ) - { - file = SceneManager->getFileSystem()->createAndOpenFile(filename); - closefile = true; - } - - if ( 0 == file ) - return 0; - - // read into memory - u8* pin = new u8[file->getSize()]; - file->read(pin, file->getSize()); - - SHalflifeHeader* header = (SHalflifeHeader*) pin; - - const bool idst = (0 == strncmp(header->id, "IDST", 4)); - const bool idsq = (0 == strncmp(header->id, "IDSQ", 4)); - - if ( (!idst && !idsq) || (idsq && !Header) ) - { - os::Printer::log("MDL Halflife Loader: Wrong file header", file->getFileName(), ELL_WARNING); - if ( closefile ) - { - file->drop(); - file = 0; - } - delete [] pin; - return 0; - } - - // don't know the real header.. idsg might be different - if (header->textureindex && idst ) - { - io::path path; - io::path fname; - io::path ext; - - core::splitFilename(file->getFileName(), &path, &fname, &ext); - TextureBaseName = path + fname + "_"; - - SHalflifeTexture *tex = (SHalflifeTexture *)(pin + header->textureindex); - u32 *palette = new u32[256]; - for (u32 i = 0; i < header->numtextures; ++i) - { - const u8 *src = pin + tex[i].index; - - // convert rgb to argb palette - { - const u8 *pal = src + tex[i].width * tex[i].height; - for( u32 g=0; g<256; ++g ) - { - palette[g] = 0xFF000000 | pal[0] << 16 | pal[1] << 8 | pal[2]; - pal += 3; - } - } - - IImage* image = SceneManager->getVideoDriver()->createImage(ECF_R8G8B8, core::dimension2d(tex[i].width, tex[i].height)); - - CColorConverter::convert8BitTo24Bit(src, (u8*)image->lock(), tex[i].width, tex[i].height, (u8*) palette, 0, false); - image->unlock(); - -#ifdef HL_TEXTURE_ATLAS - TextureAtlas.addSource ( tex[i].name, image ); -#else - core::splitFilename ( tex[i].name, 0, &fname, &ext ); - SceneManager->getVideoDriver()->addTexture ( TextureBaseName + fname, image ); - image->drop(); -#endif - } - delete [] palette; - -#ifdef HL_TEXTURE_ATLAS - TextureAtlas.create ( 2 * 2 + 1, ETC_CLAMP ); - SceneManager->getVideoDriver()->addTexture ( TextureBaseName + "atlas", TextureAtlas.Master ); - TextureAtlas.release(); -#endif - } - - if (!Header) - Header = header; - - if ( closefile ) - { - file->drop(); - file = 0; - } - - return header; -} - - -/*! -*/ -f32 CAnimatedMeshHalfLife::SetController( s32 controllerIndex, f32 value ) -{ - if (!Header) - return 0.f; - - SHalflifeBoneController *bonecontroller = (SHalflifeBoneController *)((u8*) Header + Header->bonecontrollerindex); - - // find first controller that matches the index - u32 i; - for (i = 0; i < Header->numbonecontrollers; i++, bonecontroller++) - { - if (bonecontroller->index == controllerIndex) - break; - } - if (i >= Header->numbonecontrollers) - return value; - - // wrap 0..360 if it's a rotational controller - if (bonecontroller->type & (STUDIO_XR | STUDIO_YR | STUDIO_ZR)) - { - // ugly hack, invert value if end < start - if (bonecontroller->end < bonecontroller->start) - value = -value; - - // does the controller not wrap? - if (bonecontroller->start + 359.f >= bonecontroller->end) - { - if (value > ((bonecontroller->start + bonecontroller->end) / 2.f) + 180.f) - value = value - 360.f; - if (value < ((bonecontroller->start + bonecontroller->end) / 2.f) - 180.f) - value = value + 360.f; - } - else - { - if (value > 360.f) - value = value - (s32)(value / 360.f) * 360.f; - else if (value < 0.f) - value = value + (s32)((value / -360.f) + 1) * 360.f; - } - } - - s32 range = controllerIndex == MOUTH_CONTROLLER ? 64 : 255; - - s32 setting = (s32) ( (f32) range * (value - bonecontroller->start) / (bonecontroller->end - bonecontroller->start)); - - if (setting < 0) setting = 0; - if (setting > range) setting = range; - - BoneController[controllerIndex] = setting; - - return setting * (1.f / (f32) range ) * (bonecontroller->end - bonecontroller->start) + bonecontroller->start; -} - - -/*! -*/ -u32 CAnimatedMeshHalfLife::SetSkin( u32 value ) -{ - if (value < Header->numskinfamilies) - SkinGroupSelection = value; - - return SkinGroupSelection; -} - - -/*! -*/ -bool CAnimatedMeshHalfLife::postLoadModel( const io::path &filename ) -{ - io::path path; - io::path texname; - io::path submodel; - - core::splitFilename ( filename ,&path, &texname, 0 ); - - // preload textures - // if no textures are stored in main file, use texfile - if (Header->numtextures == 0) - { - submodel = path + texname + "T.mdl"; - TextureHeader = loadModel(0, submodel); - if (!TextureHeader) - return false; - OwnTexModel = true; - } - else - { - TextureHeader = Header; - OwnTexModel = false; - } - - // preload animations - if (Header->numseqgroups > 1) - { - c8 seq[8]; - for (u32 i = 1; i < Header->numseqgroups; i++) - { - snprintf( seq, 8, "%02d.mdl", i ); - submodel = path + texname + seq; - - AnimationHeader[i] = loadModel(0, submodel); - if (!AnimationHeader[i]) - return false; - } - } - - return true; -} - - -/*! -*/ -void CAnimatedMeshHalfLife::dumpModelInfo(u32 level) const -{ - const u8 *phdr = (const u8*) Header; - const SHalflifeHeader * hdr = Header; - u32 i; - - if (level == 0) - { - printf ( - "Bones: %d\n" - "Bone Controllers: %d\n" - "Hit Boxes: %d\n" - "Sequences: %d\n" - "Sequence Groups: %d\n", - hdr->numbones, - hdr->numbonecontrollers, - hdr->numhitboxes, - hdr->numseq, - hdr->numseqgroups - ); - printf ( - "Textures: %d\n" - "Skin Families: %d\n" - "Bodyparts: %d\n" - "Attachments: %d\n" - "Transitions: %d\n", - hdr->numtextures, - hdr->numskinfamilies, - hdr->numbodyparts, - hdr->numattachments, - hdr->numtransitions); - return; - } - - printf("id: %c%c%c%c\n", phdr[0], phdr[1], phdr[2], phdr[3]); - printf("version: %d\n", hdr->version); - printf("name: \"%s\"\n", hdr->name); - printf("length: %d\n\n", hdr->length); - - printf("eyeposition: %f %f %f\n", hdr->eyeposition[0], hdr->eyeposition[1], hdr->eyeposition[2]); - printf("min: %f %f %f\n", hdr->min[0], hdr->min[1], hdr->min[2]); - printf("max: %f %f %f\n", hdr->max[0], hdr->max[1], hdr->max[2]); - printf("bbmin: %f %f %f\n", hdr->bbmin[0], hdr->bbmin[1], hdr->bbmin[2]); - printf("bbmax: %f %f %f\n", hdr->bbmax[0], hdr->bbmax[1], hdr->bbmax[2]); - - printf("flags: %d\n\n", hdr->flags); - - printf("numbones: %d\n", hdr->numbones); - for (i = 0; i < hdr->numbones; i++) - { - const SHalflifeBone *bone = (const SHalflifeBone *) (phdr + hdr->boneindex); - printf("bone %d.name: \"%s\"\n", i + 1, bone[i].name); - printf("bone %d.parent: %d\n", i + 1, bone[i].parent); - printf("bone %d.flags: %d\n", i + 1, bone[i].flags); - printf("bone %d.bonecontroller: %d %d %d %d %d %d\n", i + 1, bone[i].bonecontroller[0], bone[i].bonecontroller[1], bone[i].bonecontroller[2], bone[i].bonecontroller[3], bone[i].bonecontroller[4], bone[i].bonecontroller[5]); - printf("bone %d.value: %f %f %f %f %f %f\n", i + 1, bone[i].value[0], bone[i].value[1], bone[i].value[2], bone[i].value[3], bone[i].value[4], bone[i].value[5]); - printf("bone %d.scale: %f %f %f %f %f %f\n", i + 1, bone[i].scale[0], bone[i].scale[1], bone[i].scale[2], bone[i].scale[3], bone[i].scale[4], bone[i].scale[5]); - } - - printf("\nnumbonecontrollers: %d\n", hdr->numbonecontrollers); - const SHalflifeBoneController *bonecontrollers = (const SHalflifeBoneController *) (phdr + hdr->bonecontrollerindex); - for (i = 0; i < hdr->numbonecontrollers; i++) - { - printf("bonecontroller %d.bone: %d\n", i + 1, bonecontrollers[i].bone); - printf("bonecontroller %d.type: %d\n", i + 1, bonecontrollers[i].type); - printf("bonecontroller %d.start: %f\n", i + 1, bonecontrollers[i].start); - printf("bonecontroller %d.end: %f\n", i + 1, bonecontrollers[i].end); - printf("bonecontroller %d.rest: %d\n", i + 1, bonecontrollers[i].rest); - printf("bonecontroller %d.index: %d\n", i + 1, bonecontrollers[i].index); - } - - printf("\nnumhitboxes: %d\n", hdr->numhitboxes); - const SHalflifeBBox *box = (const SHalflifeBBox *) (phdr + hdr->hitboxindex); - for (i = 0; i < hdr->numhitboxes; i++) - { - printf("hitbox %d.bone: %d\n", i + 1, box[i].bone); - printf("hitbox %d.group: %d\n", i + 1, box[i].group); - printf("hitbox %d.bbmin: %f %f %f\n", i + 1, box[i].bbmin[0], box[i].bbmin[1], box[i].bbmin[2]); - printf("hitbox %d.bbmax: %f %f %f\n", i + 1, box[i].bbmax[0], box[i].bbmax[1], box[i].bbmax[2]); - } - - printf("\nnumseq: %d\n", hdr->numseq); - const SHalflifeSequence *seq = (const SHalflifeSequence *) (phdr + hdr->seqindex); - for (i = 0; i < hdr->numseq; i++) - { - printf("seqdesc %d.label: \"%s\"\n", i + 1, seq[i].label); - printf("seqdesc %d.fps: %f\n", i + 1, seq[i].fps); - printf("seqdesc %d.flags: %d\n", i + 1, seq[i].flags); - printf("<...>\n"); - } - - printf("\nnumseqgroups: %d\n", hdr->numseqgroups); - for (i = 0; i < hdr->numseqgroups; i++) - { - const SHalflifeSequenceGroup *group = (const SHalflifeSequenceGroup *) (phdr + hdr->seqgroupindex); - printf("\nseqgroup %d.label: \"%s\"\n", i + 1, group[i].label); - printf("\nseqgroup %d.namel: \"%s\"\n", i + 1, group[i].name); - printf("\nseqgroup %d.data: %d\n", i + 1, group[i].data); - } - - printf("\nnumskinref: %d\n", hdr->numskinref); - printf("numskinfamilies: %d\n", hdr->numskinfamilies); - - printf("\nnumbodyparts: %d\n", hdr->numbodyparts); - const SHalflifeBody *pbodyparts = (const SHalflifeBody*) ((const u8*) hdr + hdr->bodypartindex); - for (i = 0; i < hdr->numbodyparts; i++) - { - printf("bodypart %d.name: \"%s\"\n", i + 1, pbodyparts[i].name); - printf("bodypart %d.nummodels: %d\n", i + 1, pbodyparts[i].nummodels); - printf("bodypart %d.base: %d\n", i + 1, pbodyparts[i].base); - printf("bodypart %d.modelindex: %d\n", i + 1, pbodyparts[i].modelindex); - } - - printf("\nnumattachments: %d\n", hdr->numattachments); - for (i = 0; i < hdr->numattachments; i++) - { - const SHalflifeAttachment *attach = (const SHalflifeAttachment *) ((const u8*) hdr + hdr->attachmentindex); - printf("attachment %d.name: \"%s\"\n", i + 1, attach[i].name); - } - - hdr = TextureHeader; - printf("\nnumtextures: %d\n", hdr->numtextures); - printf("textureindex: %d\n", hdr->textureindex); - printf("texturedataindex: %d\n", hdr->texturedataindex); - const SHalflifeTexture *ptextures = (const SHalflifeTexture *) ((const u8*) hdr + hdr->textureindex); - for (i = 0; i < hdr->numtextures; i++) - { - printf("texture %d.name: \"%s\"\n", i + 1, ptextures[i].name); - printf("texture %d.flags: %d\n", i + 1, ptextures[i].flags); - printf("texture %d.width: %d\n", i + 1, ptextures[i].width); - printf("texture %d.height: %d\n", i + 1, ptextures[i].height); - printf("texture %d.index: %d\n", i + 1, ptextures[i].index); - } -} - - -/*! -*/ -void CAnimatedMeshHalfLife::ExtractBbox(s32 sequence, core::aabbox3df &box) const -{ - const SHalflifeSequence *seq = (const SHalflifeSequence *)((const u8*)Header + Header->seqindex) + sequence; - - box.MinEdge.X = seq[0].bbmin[0]; - box.MinEdge.Y = seq[0].bbmin[1]; - box.MinEdge.Z = seq[0].bbmin[2]; - - box.MaxEdge.X = seq[0].bbmax[0]; - box.MaxEdge.Y = seq[0].bbmax[1]; - box.MaxEdge.Z = seq[0].bbmax[2]; -} - - -/*! -*/ -void CAnimatedMeshHalfLife::calcBoneAdj() -{ - const SHalflifeBoneController *bonecontroller = - (const SHalflifeBoneController *)((const u8*) Header + Header->bonecontrollerindex); - - for (u32 j = 0; j < Header->numbonecontrollers; j++) - { - const s32 i = bonecontroller[j].index; - // check for 360% wrapping - f32 value; - if (bonecontroller[j].type & STUDIO_RLOOP) - { - value = BoneController[i] * (360.f/256.f) + bonecontroller[j].start; - } - else - { - const f32 range = i <= 3 ? 255.f : 64.f; - value = core::clamp(BoneController[i] / range,0.f,1.f); - value = (1.f - value) * bonecontroller[j].start + value * bonecontroller[j].end; - } - - switch(bonecontroller[j].type & STUDIO_TYPES) - { - case STUDIO_XR: - case STUDIO_YR: - case STUDIO_ZR: - BoneAdj[j] = value * core::DEGTORAD; - break; - case STUDIO_X: - case STUDIO_Y: - case STUDIO_Z: - BoneAdj[j] = value; - break; - } - } -} - - -/*! -*/ -void CAnimatedMeshHalfLife::calcBoneQuaternion(const s32 frame, const SHalflifeBone * const bone, - SHalflifeAnimOffset *anim, const u32 j, f32& angle1, f32& angle2) const -{ - // three vector components - if (anim->offset[j+3] == 0) - { - angle2 = angle1 = bone->value[j+3]; // default - } - else - { - SHalflifeAnimationFrame *animvalue = (SHalflifeAnimationFrame *)((u8*)anim + anim->offset[j+3]); - s32 k = frame; - while (animvalue->num.total <= k) - { - k -= animvalue->num.total; - animvalue += animvalue->num.valid + 1; - } - // Bah, missing blend! - if (animvalue->num.valid > k) - { - angle1 = animvalue[k+1].value; - - if (animvalue->num.valid > k + 1) - { - angle2 = animvalue[k+2].value; - } - else - { - if (animvalue->num.total > k + 1) - angle2 = angle1; - else - angle2 = animvalue[animvalue->num.valid+2].value; - } - } - else - { - angle1 = animvalue[animvalue->num.valid].value; - if (animvalue->num.total > k + 1) - { - angle2 = angle1; - } - else - { - angle2 = animvalue[animvalue->num.valid + 2].value; - } - } - angle1 = bone->value[j+3] + angle1 * bone->scale[j+3]; - angle2 = bone->value[j+3] + angle2 * bone->scale[j+3]; - } - - if (bone->bonecontroller[j+3] != -1) - { - angle1 += BoneAdj[bone->bonecontroller[j+3]]; - angle2 += BoneAdj[bone->bonecontroller[j+3]]; - } -} - - -/*! -*/ -void CAnimatedMeshHalfLife::calcBonePosition(const s32 frame, f32 s, - const SHalflifeBone * const bone, SHalflifeAnimOffset *anim, f32 *pos) const -{ - for (s32 j = 0; j < 3; ++j) - { - pos[j] = bone->value[j]; // default; - if (anim->offset[j] != 0) - { - SHalflifeAnimationFrame *animvalue = (SHalflifeAnimationFrame *)((u8*)anim + anim->offset[j]); - - s32 k = frame; - // find span of values that includes the frame we want - while (animvalue->num.total <= k) - { - k -= animvalue->num.total; - animvalue += animvalue->num.valid + 1; - } - // if we're inside the span - if (animvalue->num.valid > k) - { - // and there's more data in the span - if (animvalue->num.valid > k + 1) - { - pos[j] += (animvalue[k+1].value * (1.f - s) + s * animvalue[k+2].value) * bone->scale[j]; - } - else - { - pos[j] += animvalue[k+1].value * bone->scale[j]; - } - } - else - { - // are we at the end of the repeating values section and there's another section with data? - if (animvalue->num.total <= k + 1) - { - pos[j] += (animvalue[animvalue->num.valid].value * (1.f - s) + s * animvalue[animvalue->num.valid + 2].value) * bone->scale[j]; - } - else - { - pos[j] += animvalue[animvalue->num.valid].value * bone->scale[j]; - } - } - } - if (bone->bonecontroller[j] != -1) - { - pos[j] += BoneAdj[bone->bonecontroller[j]]; - } - } -} - - -/*! -*/ -void CAnimatedMeshHalfLife::calcRotations(vec3_hl *pos, vec4_hl *q, - SHalflifeSequence *seq, SHalflifeAnimOffset *anim, f32 f) -{ - s32 frame = (s32)f; - f32 s = (f - frame); - - // add in programatic controllers - calcBoneAdj(); - - SHalflifeBone *bone = (SHalflifeBone *)((u8 *)Header + Header->boneindex); - for ( u32 i = 0; i < Header->numbones; i++, bone++, anim++) - { - core::vector3df angle1, angle2; - calcBoneQuaternion(frame, bone, anim, 0, angle1.X, angle2.X); - calcBoneQuaternion(frame, bone, anim, 1, angle1.Y, angle2.Y); - calcBoneQuaternion(frame, bone, anim, 2, angle1.Z, angle2.Z); - - if (!angle1.equals(angle2)) - { - vec4_hl q1, q2; - AngleQuaternion( angle1, q1 ); - AngleQuaternion( angle2, q2 ); - QuaternionSlerp( q1, q2, s, q[i] ); - } - else - { - AngleQuaternion( angle1, q[i] ); - } - - calcBonePosition(frame, s, bone, anim, pos[i]); - } - - if (seq->motiontype & STUDIO_X) - pos[seq->motionbone][0] = 0.f; - if (seq->motiontype & STUDIO_Y) - pos[seq->motionbone][1] = 0.f; - if (seq->motiontype & STUDIO_Z) - pos[seq->motionbone][2] = 0.f; -} - - -/*! -*/ -SHalflifeAnimOffset * CAnimatedMeshHalfLife::getAnim( SHalflifeSequence *seq ) -{ - SHalflifeSequenceGroup *seqgroup = (SHalflifeSequenceGroup *)((u8*)Header + Header->seqgroupindex) + seq->seqgroup; - - if (seq->seqgroup == 0) - { - return (SHalflifeAnimOffset *)((u8*)Header + seqgroup->data + seq->animindex); - } - - return (SHalflifeAnimOffset *)((u8*)AnimationHeader[seq->seqgroup] + seq->animindex); -} - - -/*! -*/ -void CAnimatedMeshHalfLife::slerpBones(vec4_hl q1[], vec3_hl pos1[], vec4_hl q2[], vec3_hl pos2[], f32 s) -{ - if (s < 0) - s = 0; - else if (s > 1.f) - s = 1.f; - - f32 s1 = 1.f - s; - - for ( u32 i = 0; i < Header->numbones; i++) - { - vec4_hl q3; - QuaternionSlerp( q1[i], q2[i], s, q3 ); - q1[i][0] = q3[0]; - q1[i][1] = q3[1]; - q1[i][2] = q3[2]; - q1[i][3] = q3[3]; - pos1[i][0] = pos1[i][0] * s1 + pos2[i][0] * s; - pos1[i][1] = pos1[i][1] * s1 + pos2[i][1] * s; - pos1[i][2] = pos1[i][2] * s1 + pos2[i][2] * s; - } -} - - -/*! -*/ -void CAnimatedMeshHalfLife::setUpBones() -{ - static vec3_hl pos[MAXSTUDIOBONES]; - f32 bonematrix[3][4]; - static vec4_hl q[MAXSTUDIOBONES]; - - static vec3_hl pos2[MAXSTUDIOBONES]; - static vec4_hl q2[MAXSTUDIOBONES]; - static vec3_hl pos3[MAXSTUDIOBONES]; - static vec4_hl q3[MAXSTUDIOBONES]; - static vec3_hl pos4[MAXSTUDIOBONES]; - static vec4_hl q4[MAXSTUDIOBONES]; - - if (SequenceIndex >= Header->numseq) - SequenceIndex = 0; - - SHalflifeSequence *seq = (SHalflifeSequence *)((u8*) Header + Header->seqindex) + SequenceIndex; - - SHalflifeAnimOffset *anim = getAnim(seq); - calcRotations(pos, q, seq, anim, CurrentFrame); - - if (seq->numblends > 1) - { - anim += Header->numbones; - calcRotations( pos2, q2, seq, anim, CurrentFrame ); - f32 s = Blending[0] / 255.f; - - slerpBones( q, pos, q2, pos2, s ); - - if (seq->numblends == 4) - { - anim += Header->numbones; - calcRotations( pos3, q3, seq, anim, CurrentFrame ); - - anim += Header->numbones; - calcRotations( pos4, q4, seq, anim, CurrentFrame ); - - s = Blending[0] / 255.f; - slerpBones( q3, pos3, q4, pos4, s ); - - s = Blending[1] / 255.f; - slerpBones( q, pos, q3, pos3, s ); - } - } - - SHalflifeBone *bone = (SHalflifeBone *)((u8*) Header + Header->boneindex); - - for (u32 i = 0; i < Header->numbones; i++) - { - QuaternionMatrix( q[i], bonematrix ); - - bonematrix[0][3] = pos[i][0]; - bonematrix[1][3] = pos[i][1]; - bonematrix[2][3] = pos[i][2]; - - if (bone[i].parent == -1) { - memcpy(BoneTransform[i], bonematrix, sizeof(f32) * 12); - } - else { - R_ConcatTransforms (BoneTransform[bone[i].parent], bonematrix, BoneTransform[i]); - } - } -} - - -//! Returns an axis aligned bounding box -const core::aabbox3d& CAnimatedMeshHalfLife::getBoundingBox() const -{ - return MeshIPol->BoundingBox; -} - - -//! Returns the type of the animated mesh. -E_ANIMATED_MESH_TYPE CAnimatedMeshHalfLife::getMeshType() const -{ - return EAMT_MDL_HALFLIFE; -} - - -//! returns amount of mesh buffers. -u32 CAnimatedMeshHalfLife::getMeshBufferCount() const -{ - return MeshIPol->getMeshBufferCount(); -} - - -//! returns pointer to a mesh buffer -IMeshBuffer* CAnimatedMeshHalfLife::getMeshBuffer(u32 nr) const -{ - return MeshIPol->getMeshBuffer(nr); -} - - -//! Returns pointer to a mesh buffer which fits a material -/** \param material: material to search for -\return Returns the pointer to the mesh buffer or -NULL if there is no such mesh buffer. */ -IMeshBuffer* CAnimatedMeshHalfLife::getMeshBuffer(const video::SMaterial &material) const -{ - return MeshIPol->getMeshBuffer(material); -} - - -void CAnimatedMeshHalfLife::setMaterialFlag(video::E_MATERIAL_FLAG flag, bool newvalue) -{ - MeshIPol->setMaterialFlag ( flag, newvalue ); -} - - -//! set user axis aligned bounding box -void CAnimatedMeshHalfLife::setBoundingBox(const core::aabbox3df& box) -{ - MeshIPol->setBoundingBox(box); -} - - -} // end namespace scene -} // end namespace irr - -#endif // _IRR_COMPILE_WITH_MD3_LOADER_ - diff --git a/lib/irrlicht/source/Irrlicht/CAnimatedMeshHalfLife.h b/lib/irrlicht/source/Irrlicht/CAnimatedMeshHalfLife.h deleted file mode 100644 index 32a4ef802..000000000 --- a/lib/irrlicht/source/Irrlicht/CAnimatedMeshHalfLife.h +++ /dev/null @@ -1,630 +0,0 @@ -// Copyright (C) 2002-2012 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 -{ - - - // 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 - -// byte-align structures -#include "irrpack.h" - - 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; - } PACK_STRUCT; - - // header for demand loaded sequence group data - struct studioseqhdr_t - { - s32 id; - s32 version; - - c8 name[64]; - s32 length; - } PACK_STRUCT; - - // 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 - } PACK_STRUCT; - - - // 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 - } PACK_STRUCT; - - // intersection boxes - struct SHalflifeBBox - { - s32 bone; - s32 group; // intersection group - vec3_hl bbmin; // bounding box - vec3_hl bbmax; - } PACK_STRUCT; - -#ifndef ZONE_H - // NOTE: this was a void*, but that crashes on 64bit. - // I have found no mdl format desc, so not sure what it's meant to be, but s32 at least works. - typedef s32 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 - } PACK_STRUCT; - - // 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 - } PACK_STRUCT; - - // events - struct mstudioevent_t - { - s32 frame; - s32 event; - s32 type; - c8 options[64]; - } PACK_STRUCT; - - - // pivots - struct mstudiopivot_t - { - vec3_hl org; // pivot point - s32 start; - s32 end; - } PACK_STRUCT; - - // attachment - struct SHalflifeAttachment - { - c8 name[32]; - s32 type; - s32 bone; - vec3_hl org; // attachment point - vec3_hl vectors[3]; - } PACK_STRUCT; - - struct SHalflifeAnimOffset - { - u16 offset[6]; - } PACK_STRUCT; - - // animation frames - union SHalflifeAnimationFrame - { - struct { - u8 valid; - u8 total; - } PACK_STRUCT num; - s16 value; - } PACK_STRUCT; - - - // body part index - struct SHalflifeBody - { - c8 name[64]; - u32 nummodels; - u32 base; - u32 modelindex; // index into models array - } PACK_STRUCT; - - - // skin info - struct SHalflifeTexture - { - c8 name[64]; - s32 flags; - s32 width; - s32 height; - s32 index; - } PACK_STRUCT; - - - // 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; - } PACK_STRUCT; - - - // meshes - struct SHalflifeMesh - { - u32 numtris; - u32 triindex; - u32 skinref; - u32 numnorms; // per mesh normals - u32 normindex; // normal vec3_hl - } PACK_STRUCT; - -// Default alignment -#include "irrunpack.h" - - // 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) - - /*! - 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; - }; - - - //! 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), - CurrentFrame ( (f32) start ), NextFrame ( start ), StartFrame ( start ), - Frames ( frames ), LoopingFrames ( loopingframes ), EndFrame ( start + frames - 1 ), - FramesPerSecond ( fps ), RelativeSpeed ( relativefps ), - 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; - - - 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& 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); - - //! Gets the default animation speed of the animated mesh. - /** \return Amount of frames per second. If the amount is 0, it is a static, non animated mesh. */ - virtual f32 getAnimationSpeed() const - { - return FramesPerSecond; - } - - //! Gets the frame count of the animated mesh. - /** \param fps Frames per second to play the animation with. If the amount is 0, it is not animated. - The actual speed is set in the scene node the mesh is instantiated in.*/ - virtual void setAnimationSpeed(f32 fps) - { - FramesPerSecond=fps; - } - - //! 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 (); - SHalflifeHeader * loadModel( io::IReadFile* file, const io::path &filename ); - bool postLoadModel( const io::path &filename ); - - u32 SequenceIndex; // sequence index - f32 CurrentFrame; // Current Frame - f32 FramesPerSecond; - - #define MOUTH_CONTROLLER 4 - u8 BoneController[4 + 1 ]; // bone controllers + mouth position - u8 Blending[2]; // animation blending - - vec4_hl BoneAdj; - f32 SetController( s32 controllerIndex, f32 value ); - - u32 SkinGroupSelection; // skin group selection - u32 SetSkin( u32 value ); - - void initModel(); - void dumpModelInfo(u32 level) const; - - void ExtractBbox(s32 sequence, core::aabbox3df &box) const; - - 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 ); - - void calcBoneAdj(); - void calcBoneQuaternion(const s32 frame, const SHalflifeBone *bone, SHalflifeAnimOffset *anim, const u32 j, f32& angle1, f32& angle2) const; - void calcBonePosition(const s32 frame, f32 s, const 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 -