diff --git a/changes.txt b/changes.txt index 83ede9d4..c0b8de97 100644 --- a/changes.txt +++ b/changes.txt @@ -1,4 +1,79 @@ -Changes in version 1.6 +Changes in 1.6 TA + - fixed createMeshWith2TCoords + normals were missing during copy. + - addded + //! Creates a copy of the mesh, which will only consist of S3DVertex vertices. + IMesh* CMeshManipulator::createMeshWith1TCoords(IMesh* mesh) const + + - added io::IFileSystem* CSceneManager::getFileSystem() + for preparing to remove the (mostly) unnecessary double member variables + in many loaders + + - added virtual const c8* ISceneManager::getAnimatorTypeName(ESCENE_NODE_ANIMATOR_TYPE type); + to the SceneManger Interface. just like getTypeName is public + + - added CSceneNodeAnimatorFlyCircle::radiusEllipsoid. + if radiusEllipsoid == 0 the default circle animation is done + else radiusEllipsoid forms the b-axe of the ellipsoid. + + -> gummiball bouncing + + - added ISceneManager::createFlyStraightAnimator variable bool ping-pong + used in loop mode to device if start from beginning ( default ) or make ping-pong + + -> straight bouncing + + - changed IFileSystem::registerFileArchive + remove the index of the hiarchy and added a new interface method + + //! move the hirarchy of the filesystem. moves sourceIndex relative up or down + virtual bool moveFileArchive( u32 sourceIndex, s32 relative ) = 0; + + + - bugfix and changes in + SViewFrustum::SViewFrustum + wrong size of Matrices copy. This bug must be ages old... (typo) + detected during resizing the Matrices. removed obsolute Matrices + renamed E_TRANSFORMATION_STATE_2 to E_TRANSFORMATION_STATE_FRUSTUM + + therefore also changed SViewFrustum::setTransformState to not tap + in the pitfall again of wrong memory... + and renamed it to getTransform, like in the driver + and Matrices private + + - OpenGL: + Specular + - moved + //! EMT_ONETEXTURE_BLEND: has BlendFactor Alphablending + inline bool textureBlendFunc_hasAlpha ( E_BLEND_FACTOR factor ) const + from the material renderes ( 3x declared ) to SMaterial.h + + - updated managed light example to use standard driver selection + - BurningsVideo + - LightModel reworked. + Point Light & Direction Light works for Diffuse Color as aspected + Specular and Fog still have problems ( needs new pixel shader ) + pushed burningsvideo to 0.42 for this major step + + - removed obsolete matrix transformations + renamed E_TRANSFORMATION_STATE_2 to E_TRANSFORMATION_STATE_BURNING + + + - cleaned line3d.h vector3d.h template behavior. + many mixed f32/f64 implementations are here. i'm not sure if this should be + the default behavior to use f64 for example for 1.0/x value, because they + benefit from more precisions, but in my point of view the user is responsible + of choosing a vector3d or vector3d. + - added core::squareroot to irrmath.h + -> for having candidates for faster math in the same file + - added AllowZWriteOnTransparent from SceneManager to burningsvideo + Following SceneManger guideline + -added hasAlpha() to ITexture + This info can be used for e.q to downgrade a transparent alpha channel blit + to add if the texture has no alpha channel. + +-------------------------------------------------------------- +Changes in version 1.6, TA - FileSystem 2.0 SUPER MASTER MAJOR API CHANGE !!! diff --git a/examples/11.PerPixelLighting/main.cpp b/examples/11.PerPixelLighting/main.cpp index b60eb833..a527fc77 100644 --- a/examples/11.PerPixelLighting/main.cpp +++ b/examples/11.PerPixelLighting/main.cpp @@ -362,6 +362,8 @@ int main() smgr->addLightSceneNode(0, core::vector3df(0,0,0), video::SColorf(0.5f, 1.0f, 0.5f, 0.0f), 800.0f); + light1->setDebugDataVisible ( scene::EDS_BBOX ); + // add fly circle animator to light 1 scene::ISceneNodeAnimator* anim = diff --git a/examples/16.Quake3MapShader/main.cpp b/examples/16.Quake3MapShader/main.cpp index 075091ef..49af0e6a 100644 --- a/examples/16.Quake3MapShader/main.cpp +++ b/examples/16.Quake3MapShader/main.cpp @@ -269,18 +269,6 @@ int IRRCALLCONV main(int argc, char* argv[]) #ifndef SHOW_SHADER_NAME smgr->addQuake3SceneNode ( meshBuffer, shader ); #else - // Now add the MeshBuffer(s) with the current Shader to the Manager -#if 0 - if ( shader->name != "textures/cf/window-decal" - ) - continue; -#endif - if ( 0 == count ) - { - core::stringc s; - //quake3::dumpShader ( s, shader ); - printf ( s.c_str () ); - } count += 1; node = smgr->addQuake3SceneNode ( meshBuffer, shader ); @@ -321,12 +309,12 @@ int IRRCALLCONV main(int argc, char* argv[]) */ if ( mesh ) { - const quake3::tQ3EntityList &entityList = mesh->getEntityList (); + quake3::tQ3EntityList &entityList = mesh->getEntityList (); quake3::SEntity search; search.name = "info_player_deathmatch"; - s32 index = entityList.binary_search_const ( search ); + s32 index = entityList.binary_search ( search ); if ( index >= 0 ) { const quake3::SVarGroup *group; diff --git a/examples/20.ManagedLights/main.cpp b/examples/20.ManagedLights/main.cpp index 1a46e625..b738a605 100644 --- a/examples/20.ManagedLights/main.cpp +++ b/examples/20.ManagedLights/main.cpp @@ -273,7 +273,8 @@ private: }; - +/*! +*/ int main(int argumentCount, char * argumentValues[]) { char driverChoice; @@ -284,7 +285,8 @@ int main(int argumentCount, char * argumentValues[]) { printf("Please select the driver you want for this example:\n"\ " (a) Direct3D 9.0c\n (b) Direct3D 8.1\n (c) OpenGL 1.5\n"\ - " (d) Burning's Software Renderer\n(otherKey) exit\n\n"); + " (d) Software Renderer\n (e) Burning's Software Renderer\n"\ + " (f) NullDevice\n (otherKey) exit\n\n"); std::cin >> driverChoice; } @@ -295,10 +297,13 @@ int main(int argumentCount, char * argumentValues[]) case 'a': driverType = video::EDT_DIRECT3D9;break; case 'b': driverType = video::EDT_DIRECT3D8;break; case 'c': driverType = video::EDT_OPENGL; break; - case 'd': driverType = video::EDT_BURNINGSVIDEO; break; + case 'd': driverType = video::EDT_SOFTWARE; break; + case 'e': driverType = video::EDT_BURNINGSVIDEO;break; + case 'f': driverType = video::EDT_NULL; break; default: return 0; } + IrrlichtDevice *device = createDevice(driverType, dimension2d(640, 480), 32, false, false, false, 0); if(!device) diff --git a/examples/21.Quake3Explorer/main.cpp b/examples/21.Quake3Explorer/main.cpp index f84d0885..483d4e73 100644 --- a/examples/21.Quake3Explorer/main.cpp +++ b/examples/21.Quake3Explorer/main.cpp @@ -30,7 +30,8 @@ struct GameData { GameData ( const string &startupDir); void setDefault (); - s32 save (); + s32 save ( const string filename ); + s32 load ( const string filename ); s32 debugState; s32 gravityState; @@ -93,7 +94,7 @@ void GameData::setDefault () loadParam.defaultLightMapMaterial = EMT_LIGHTMAP; loadParam.defaultModulate = EMFN_MODULATE_1X; loadParam.verbose = 1; - loadParam.mergeShaderBuffer = 1; + loadParam.mergeShaderBuffer = 1; // merge meshbuffers with same material loadParam.cleanUnResolvedMeshes = 1; // should unresolved meshes be cleaned. otherwise blue texture loadParam.loadAllShaders = 1; // load all scripts in the script directory loadParam.loadSkyShader = 0; // load sky Shader @@ -104,14 +105,29 @@ void GameData::setDefault () CurrentMapName = ""; CurrentArchiveList.clear (); CurrentArchiveList.push_back ( StartupDir + "../../media/" ); + CurrentArchiveList.push_back ( "/q/baseq3/" ); CurrentArchiveList.push_back ( StartupDir + "../../media/map-20kdm2.pk3" ); } +/*! + Load the current game State +*/ +s32 GameData::load ( const string filename ) +{ + if ( 0 == Device ) + return 0; + + //! the quake3 mesh loader can also handle *.shader and *.cfg file + IQ3LevelMesh* mesh = (IQ3LevelMesh*) Device->getSceneManager()->getMesh ( filename ); + + return 1; +} + /*! Store the current game State */ -s32 GameData::save () +s32 GameData::save ( const string filename ) { if ( 0 == Device ) return 0; @@ -120,7 +136,7 @@ s32 GameData::save () // Store current Archive for restart CurrentArchiveList.clear(); - io::IFileSystem *fs = Device->getFileSystem(); + IFileSystem *fs = Device->getFileSystem(); for ( i = 0; i != fs->getFileArchiveCount(); ++i ) { CurrentArchiveList.push_back ( fs->getFileArchive ( i )->getArchiveName() ); @@ -133,7 +149,17 @@ s32 GameData::save () PlayerPosition = camera->getPosition (); PlayerRotation = camera->getRotation (); } + + IWriteFile *file = fs->createAndWriteFile ( filename ); + if ( 0 == file ) + return 0; + c8 buf[128]; + snprintf ( buf, 128, "playerposition %.f %.f %.f\nplayerrotation %.f %.f %.f\n", + PlayerPosition.X, PlayerPosition.Y, PlayerPosition.Z, + PlayerRotation.X, PlayerRotation.Y, PlayerRotation.Z); + file->write ( buf, (s32) strlen ( buf ) ); + file->drop (); return 1; } @@ -365,29 +391,7 @@ struct GUI { GUI () { - Window = 0; - SetVideoMode = 0; - Bit32 = 0; - MultiSample = 0; - FullScreen = 0; - VideoMode = 0; - VideoDriver = 0; - StatusLine = 0; - SceneTree = 0; - Tesselation = 0; - Gamma = 0; - Collision = 0; - Visible_Map = 0; - Visible_Shader = 0; - Visible_Fog = 0; - Visible_Unresolved = 0; - Respawn = 0; - MapList = 0; - Logo = 0; - ArchiveList = 0; - ArchiveAdd = 0; - ArchiveRemove = 0; - ArchiveFileOpen = 0; + memset ( this, 0, sizeof ( *this ) ); } void drop() @@ -410,12 +414,15 @@ struct GUI IGUICheckBox* Visible_Shader; IGUICheckBox* Visible_Fog; IGUICheckBox* Visible_Unresolved; + IGUICheckBox* Visible_Skydome; IGUIButton* Respawn; IGUITable* ArchiveList; IGUIButton* ArchiveAdd; IGUIButton* ArchiveRemove; IGUIFileOpenDialog* ArchiveFileOpen; + IGUIButton* ArchiveUp; + IGUIButton* ArchiveDown; IGUIListBox* MapList; IGUITreeView* SceneTree; @@ -516,7 +523,7 @@ CQuake3EventHandler::~CQuake3EventHandler () Player[0].shutdown (); sound_shutdown (); - Game->save(); + Game->save( "explorer.cfg" ); Game->Device->drop(); } @@ -709,14 +716,21 @@ void CQuake3EventHandler::CreateGUI() gui.Visible_Fog->setToolTipText ( L"Show or not show the Fog Nodes. \nPress F5 on your Keyboard" ); gui.Visible_Unresolved = env->addCheckBox ( true, rect( dim.Width - 110, 150, dim.Width - 10, 166 ), gui.Window,-1, L"Unresolved" ); gui.Visible_Unresolved->setToolTipText ( L"Show the or not show the Nodes the Engine can't handle. \nPress F6 on your Keyboard" ); + gui.Visible_Skydome = env->addCheckBox ( true, rect( dim.Width - 110, 180, dim.Width - 10, 196 ), gui.Window,-1, L"Skydome" ); + gui.Visible_Skydome->setToolTipText ( L"Show the or not show the Skydome." ); //Respawn = env->addButton ( rect( dim.Width - 260, 90, dim.Width - 10, 106 ), 0,-1, L"Respawn" ); env->addStaticText ( L"Archives:", rect( 5, dim.Height - 530, dim.Width - 600,dim.Height - 514 ),false, false, gui.Window, -1, false ); - gui.ArchiveAdd = env->addButton ( rect( dim.Width - 700, dim.Height - 530, dim.Width - 620, dim.Height - 514 ), gui.Window,-1, L"add" ); - gui.ArchiveAdd->setToolTipText ( L"Add an archive, usally packed zip-archives (*.pk3) to the Filesystem" ); - gui.ArchiveRemove = env->addButton ( rect( dim.Width - 600, dim.Height - 530, dim.Width - 520, dim.Height - 514 ), gui.Window,-1, L"del" ); + + gui.ArchiveAdd = env->addButton ( rect( dim.Width - 725, dim.Height - 530, dim.Width - 665, dim.Height - 514 ), gui.Window,-1, L"add" ); + gui.ArchiveAdd->setToolTipText ( L"Add an archive, usually packed zip-archives (*.pk3) to the Filesystem" ); + gui.ArchiveRemove = env->addButton ( rect( dim.Width - 660, dim.Height - 530, dim.Width - 600, dim.Height - 514 ), gui.Window,-1, L"del" ); gui.ArchiveRemove->setToolTipText ( L"Remove the selected archive from the FileSystem." ); + gui.ArchiveUp = env->addButton ( rect( dim.Width - 575, dim.Height - 530, dim.Width - 515, dim.Height - 514 ), gui.Window,-1, L"up" ); + gui.ArchiveUp->setToolTipText ( L"Arrange Archive Look-up Hirachy. Move the selected Archive up" ); + gui.ArchiveDown = env->addButton ( rect( dim.Width - 510, dim.Height - 530, dim.Width - 440, dim.Height - 514 ), gui.Window,-1, L"down" ); + gui.ArchiveDown->setToolTipText ( L"Arrange Archive Look-up Hirachy. Move the selected Archive down" ); gui.ArchiveList = env->addTable ( rect( 5,dim.Height - 510, dim.Width - 450,dim.Height - 410 ), gui.Window ); @@ -765,7 +779,7 @@ void CQuake3EventHandler::CreateGUI() */ void CQuake3EventHandler::AddArchive ( const core::string& archiveName ) { - io::IFileSystem *fs = Game->Device->getFileSystem(); + IFileSystem *fs = Game->Device->getFileSystem(); u32 i; if ( archiveName.size () ) @@ -794,9 +808,9 @@ void CQuake3EventHandler::AddArchive ( const core::string& archiveName ) for ( i = 0; i != fs->getFileArchiveCount(); ++i ) { - io::IFileArchive * archive = fs->getFileArchive ( i ); + IFileArchive * archive = fs->getFileArchive ( i ); - u32 index = gui.ArchiveList->addRow(0xffffffff); + u32 index = gui.ArchiveList->addRow(i); gui.ArchiveList->setCellText ( index, 0, archive->getArchiveType () ); gui.ArchiveList->setCellText ( index, 1, archive->getArchiveName () ); @@ -825,10 +839,10 @@ void CQuake3EventHandler::AddArchive ( const core::string& archiveName ) core::stringw s; //! browse the attached file system - fs->setFileListSystem ( io::FILESYSTEM_VIRTUAL ); + fs->setFileListSystem ( FILESYSTEM_VIRTUAL ); fs->changeWorkingDirectoryTo ( "/maps/" ); - io::IFileList *fileList = fs->createFileList (); - fs->setFileListSystem ( io::FILESYSTEM_NATIVE ); + IFileList *fileList = fs->createFileList (); + fs->setFileListSystem ( FILESYSTEM_NATIVE ); for ( i=0; i< fileList->getFileCount(); ++i) { @@ -848,11 +862,13 @@ void CQuake3EventHandler::AddArchive ( const core::string& archiveName ) string filename; filename = c + ".jpg"; - image = driver->createImageFromFile( filename ); + if ( fs->existFile ( filename ) ) + image = driver->createImageFromFile( filename ); if ( 0 == image ) { filename = c + ".tga"; - image = driver->createImageFromFile( filename ); + if ( fs->existFile ( filename ) ) + image = driver->createImageFromFile( filename ); } if ( image ) @@ -930,11 +946,11 @@ void CQuake3EventHandler::dropMap () dropElement ( MapParent ); dropElement ( SkyNode ); - if ( Mesh ) - { - Game->Device->getSceneManager ()->getMeshCache()->removeMesh ( Mesh ); - Mesh = 0; - } + // clean out meshes, because textures are invalid + // TODO: better texture handling;-) + IMeshCache *cache = Game->Device->getSceneManager ()->getMeshCache(); + cache->clear (); + Mesh = 0; } /*! @@ -946,10 +962,10 @@ void CQuake3EventHandler::LoadMap ( const stringw &mapName, s32 collision ) dropMap (); - io::IFileSystem *fs = Game->Device->getFileSystem(); + IFileSystem *fs = Game->Device->getFileSystem(); ISceneManager *smgr = Game->Device->getSceneManager (); - io::IReadFile* file = fs->createMemoryReadFile ( &Game->loadParam, sizeof ( Game->loadParam ), + IReadFile* file = fs->createMemoryReadFile ( &Game->loadParam, sizeof ( Game->loadParam ), L"levelparameter.cfg", false); smgr->getMesh( file ); @@ -1075,8 +1091,33 @@ void CQuake3EventHandler::addSceneTreeItem( ISceneNode * parent, IGUITreeViewNod swprintf ( msg, 128, L"%hs",(*it)->getName() ); } - node = nodeParent->addChildBack( msg, 0, imageIndex ); + + // Add all Animators + list::ConstIterator ait = (*it)->getAnimators().begin(); + for (; ait != (*it)->getAnimators().end(); ++ait) + { + imageIndex = -1; + swprintf ( msg, 128, L"%hs", + Game->Device->getSceneManager ()->getAnimatorTypeName ( (*ait)->getType () ) + ); + + switch ( (*ait)->getType () ) + { + case ESNAT_FLY_CIRCLE: + case ESNAT_FLY_STRAIGHT: + case ESNAT_FOLLOW_SPLINE: + case ESNAT_ROTATION: + case ESNAT_TEXTURE: + case ESNAT_DELETION: + case ESNAT_COLLISION_RESPONSE: + case ESNAT_CAMERA_FPS: + case ESNAT_CAMERA_MAYA: + break; + } + node->addChildBack( msg, 0, imageIndex ); + } + addSceneTreeItem ( *it, node ); } @@ -1240,7 +1281,7 @@ bool CQuake3EventHandler::OnEvent(const SEvent& eve) { if ( 0 == gui.ArchiveFileOpen ) { - Game->Device->getFileSystem()->setFileListSystem ( io::FILESYSTEM_NATIVE ); + Game->Device->getFileSystem()->setFileListSystem ( FILESYSTEM_NATIVE ); gui.ArchiveFileOpen = Game->Device->getGUIEnvironment()->addFileOpenDialog ( L"Add Game Archive" , false,gui.Window ); } } @@ -1261,6 +1302,19 @@ bool CQuake3EventHandler::OnEvent(const SEvent& eve) gui.ArchiveFileOpen = 0; } else + if ( ( eve.GUIEvent.Caller == gui.ArchiveUp || eve.GUIEvent.Caller == gui.ArchiveDown ) && + eve.GUIEvent.EventType == gui::EGET_BUTTON_CLICKED ) + { + s32 rel = eve.GUIEvent.Caller == gui.ArchiveUp ? -1 : 1; + if ( Game->Device->getFileSystem()->moveFileArchive ( gui.ArchiveList->getSelected (), rel ) ) + { + s32 newIndex = core::s32_clamp ( gui.ArchiveList->getSelected() + rel, 0, gui.ArchiveList->getRowCount() - 1 ); + AddArchive ( "" ); + gui.ArchiveList->setSelected ( newIndex ); + Game->CurrentMapName = ""; + } + } + else if ( eve.GUIEvent.Caller == gui.VideoDriver && eve.GUIEvent.EventType == gui::EGET_COMBO_BOX_CHANGED ) { Game->deviceParam.DriverType = (E_DRIVER_TYPE) gui.VideoDriver->getItemData ( gui.VideoDriver->getSelected() ); @@ -1341,6 +1395,16 @@ bool CQuake3EventHandler::OnEvent(const SEvent& eve) } } else + if ( eve.GUIEvent.Caller == gui.Visible_Skydome && eve.GUIEvent.EventType == gui::EGET_CHECKBOX_CHANGED ) + { + if ( SkyNode ) + { + bool v = !SkyNode->isVisible(); + printf ( "skynode set visible %d\n",v ); + SkyNode->setVisible ( v ); + } + } + else if ( eve.GUIEvent.Caller == gui.Respawn && eve.GUIEvent.EventType == gui::EGET_BUTTON_CLICKED ) { Player[0].respawn (); @@ -1429,6 +1493,15 @@ bool CQuake3EventHandler::OnEvent(const SEvent& eve) EDS_NORMALS | EDS_MESH_WIRE_OVERLAY | EDS_BBOX_ALL: EDS_OFF; */ + if ( ItemParent ) + { + list::ConstIterator it = ItemParent->getChildren().begin(); + for (; it != ItemParent->getChildren().end(); ++it) + { + (*it)->setDebugDataVisible ( value ); + } + } + if ( ShaderParent ) { list::ConstIterator it = ShaderParent->getChildren().begin(); @@ -1815,7 +1888,7 @@ void CQuake3EventHandler::Animate() wchar_t msg[128]; IVideoDriver * driver = Game->Device->getVideoDriver(); - io::IAttributes * attr = smgr->getParameters(); + IAttributes * attr = smgr->getParameters(); swprintf ( msg, 128, L"Q3 %s [%s], FPS:%03d Tri:%.03fm Cull %d/%d nodes (%d,%d,%d)", Game->CurrentMapName.c_str(), @@ -1872,6 +1945,9 @@ void runGame ( GameData *game ) // create an event receiver based on current game data CQuake3EventHandler *eventHandler = new CQuake3EventHandler( game ); + //! load stored config + game->load ( "explorer.cfg" ); + //! add our media directory and archive to the file system for ( u32 i = 0; i < game->CurrentArchiveList.size(); ++i ) { @@ -1910,7 +1986,7 @@ void runGame ( GameData *game ) { eventHandler->Animate (); eventHandler->Render (); - if ( !game->Device->isWindowActive() ) + //if ( !game->Device->isWindowActive() ) game->Device->yield(); } diff --git a/examples/21.Quake3Explorer/q3factory.cpp b/examples/21.Quake3Explorer/q3factory.cpp index cbb395c4..b38f68da 100644 --- a/examples/21.Quake3Explorer/q3factory.cpp +++ b/examples/21.Quake3Explorer/q3factory.cpp @@ -25,7 +25,8 @@ static const SItemElement Quake3ItemElement [] = { "25 Health", 25, HEALTH, - SUB_NONE + SUB_NONE, + SPECIAL_SFX_BOUNCE | SPECIAL_SFX_ROTATE_1 }, { "item_health_large", "models/powerups/health/large_cross.md3", @@ -35,7 +36,8 @@ static const SItemElement Quake3ItemElement [] = { "50 Health", 50, HEALTH, - SUB_NONE + SUB_NONE, + SPECIAL_SFX_BOUNCE | SPECIAL_SFX_ROTATE_1 }, { "item_health_mega", @@ -47,6 +49,7 @@ static const SItemElement Quake3ItemElement [] = { 100, HEALTH, SUB_NONE, + SPECIAL_SFX_BOUNCE | SPECIAL_SFX_ROTATE_1 }, { "item_health_small", @@ -58,6 +61,7 @@ static const SItemElement Quake3ItemElement [] = { 5, HEALTH, SUB_NONE, + SPECIAL_SFX_BOUNCE | SPECIAL_SFX_ROTATE_1 }, { "ammo_bullets", "models/powerups/ammo/machinegunam.md3", @@ -67,7 +71,8 @@ static const SItemElement Quake3ItemElement [] = { "Bullets", 50, AMMO, - MACHINEGUN + MACHINEGUN, + SPECIAL_SFX_BOUNCE, }, { "ammo_cells", @@ -79,6 +84,7 @@ static const SItemElement Quake3ItemElement [] = { 30, AMMO, PLASMAGUN, + SPECIAL_SFX_BOUNCE }, { "ammo_rockets", "models/powerups/ammo/rocketam.md3", @@ -89,6 +95,7 @@ static const SItemElement Quake3ItemElement [] = { 5, AMMO, ROCKET_LAUNCHER, + SPECIAL_SFX_ROTATE }, { "ammo_shells", @@ -100,6 +107,7 @@ static const SItemElement Quake3ItemElement [] = { 10, AMMO, SHOTGUN, + SPECIAL_SFX_ROTATE }, { "ammo_slugs", @@ -111,6 +119,7 @@ static const SItemElement Quake3ItemElement [] = { 10, AMMO, RAILGUN, + SPECIAL_SFX_ROTATE }, { "item_armor_body", @@ -122,6 +131,7 @@ static const SItemElement Quake3ItemElement [] = { 100, ARMOR, SUB_NONE, + SPECIAL_SFX_ROTATE }, { "item_armor_combat", @@ -133,6 +143,7 @@ static const SItemElement Quake3ItemElement [] = { 50, ARMOR, SUB_NONE, + SPECIAL_SFX_ROTATE }, { "item_armor_shard", @@ -140,10 +151,11 @@ static const SItemElement Quake3ItemElement [] = { "", "sound/misc/ar1_pkup.wav", "icons/iconr_shard", - "Armor Shard", + "Armor Shared", 5, ARMOR, SUB_NONE, + SPECIAL_SFX_ROTATE }, { "weapon_gauntlet", @@ -155,6 +167,7 @@ static const SItemElement Quake3ItemElement [] = { 0, WEAPON, GAUNTLET, + SPECIAL_SFX_ROTATE }, { "weapon_shotgun", @@ -166,6 +179,7 @@ static const SItemElement Quake3ItemElement [] = { 10, WEAPON, SHOTGUN, + SPECIAL_SFX_ROTATE }, { "weapon_machinegun", @@ -177,6 +191,7 @@ static const SItemElement Quake3ItemElement [] = { 40, WEAPON, MACHINEGUN, + SPECIAL_SFX_ROTATE }, { "weapon_grenadelauncher", @@ -188,6 +203,7 @@ static const SItemElement Quake3ItemElement [] = { 10, WEAPON, GRENADE_LAUNCHER, + SPECIAL_SFX_ROTATE }, { "weapon_rocketlauncher", @@ -199,6 +215,7 @@ static const SItemElement Quake3ItemElement [] = { 10, WEAPON, ROCKET_LAUNCHER, + SPECIAL_SFX_ROTATE }, { "weapon_lightning", @@ -210,6 +227,7 @@ static const SItemElement Quake3ItemElement [] = { 100, WEAPON, LIGHTNING, + SPECIAL_SFX_ROTATE }, { "weapon_railgun", @@ -221,6 +239,7 @@ static const SItemElement Quake3ItemElement [] = { 10, WEAPON, RAILGUN, + SPECIAL_SFX_ROTATE }, { "weapon_plasmagun", @@ -232,6 +251,7 @@ static const SItemElement Quake3ItemElement [] = { 50, WEAPON, PLASMAGUN, + SPECIAL_SFX_ROTATE }, { "weapon_bfg", @@ -243,6 +263,7 @@ static const SItemElement Quake3ItemElement [] = { 20, WEAPON, BFG, + SPECIAL_SFX_ROTATE }, { "weapon_grapplinghook", @@ -254,6 +275,7 @@ static const SItemElement Quake3ItemElement [] = { 0, WEAPON, GRAPPLING_HOOK, + SPECIAL_SFX_ROTATE }, { "" @@ -261,6 +283,7 @@ static const SItemElement Quake3ItemElement [] = { }; + /*! */ const SItemElement * getItemElement ( const stringc& key ) @@ -432,7 +455,7 @@ void Q3ShaderFactory ( Q3LevelLoadParameter &loadParam, if ( takeOriginal ) { - m = new SMesh; + m = new SMesh (); ((SMesh*) m )->addMeshBuffer (meshBuffer); } else @@ -476,6 +499,7 @@ void Q3ShaderFactory ( Q3LevelLoadParameter &loadParam, /*! + create Items from Entity */ void Q3ModelFactory ( Q3LevelLoadParameter &loadParam, IrrlichtDevice *device, @@ -513,10 +537,17 @@ void Q3ModelFactory ( Q3LevelLoadParameter &loadParam, SMD3Mesh * mesh; const SMD3MeshBuffer *meshBuffer; IMeshSceneNode* node; + ISceneNodeAnimator* anim; const IShader *shader; u32 pos; vector3df p; + u32 nodeCount = 0; + tTexArray textureArray; + bool showShaderName = true; + IGUIFont *font = 0; + if ( showShaderName ) + font = device->getGUIEnvironment()->getFont("fontlucida.png"); const SItemElement *itemElement; @@ -530,6 +561,8 @@ void Q3ModelFactory ( Q3LevelLoadParameter &loadParam, pos = 0; p = getAsVector3df ( entity[index].getGroup(1)->get ( "origin" ), pos ); + nodeCount += 1; + showShaderName = true; for ( u32 g = 0; g < 2; ++g ) { if ( 0 == itemElement->model[g] || itemElement->model[g][0] == 0 ) @@ -545,22 +578,79 @@ void Q3ModelFactory ( Q3LevelLoadParameter &loadParam, if ( 0 == meshBuffer ) continue; - shader = masterMesh->getShader ( meshBuffer->Shader, false ); - if ( 0 == shader ) + shader = masterMesh->getShader ( meshBuffer->Shader.c_str(), false ); + IMeshBuffer *final = model->getMesh(0)->getMeshBuffer(j); + if ( shader ) + { + //!TODO: Hack don't modify the vertexbuffer. make it better;-) + final->getMaterial().ColorMask = 0; + node = smgr->addQuake3SceneNode ( final, shader, parent ); + final->getMaterial().ColorMask = 15; + } + else + { + // clone mesh + SMesh * m = new SMesh (); + m->addMeshBuffer ( final ); + node = smgr->addMeshSceneNode ( m, parent ); + m->drop(); + } + + if ( 0 == node ) { snprintf ( buf, 128, "q3ModelFactory shader %s failed", meshBuffer->Shader.c_str() ); device->getLogger()->log ( buf ); continue; } - node = smgr->addQuake3SceneNode ( model->getMesh(0)->getMeshBuffer(j), shader, parent ); - if ( 0 == node ) - continue; - - node->setName ( shader->name.c_str () ); + // node was maybe centered by shaderscenenode node->setPosition ( p ); + node->setName ( meshBuffer->Shader ); + node->setAutomaticCulling ( scene::EAC_BOX ); + + // add special effects to node + if ( itemElement->special & SPECIAL_SFX_ROTATE || + (g == 0 && itemElement->special & SPECIAL_SFX_ROTATE_1) + ) + { + anim = smgr->createRotationAnimator ( vector3df ( 0.f, + 2.f, 0.f ) ); + node->addAnimator ( anim ); + anim->drop (); + } + continue; + if ( itemElement->special & SPECIAL_SFX_BOUNCE ) + { + //anim = smgr->createFlyStraightAnimator ( + // p, p + vector3df ( 0.f, 60.f, 0.f ), 1000, true, true ); + anim = smgr->createFlyCircleAnimator ( + p + vector3df( 0.f, 20.f, 0.f ), + 20.f, + 0.005f, + vector3df ( 1.f, 0.f, 0.f ), + core::fract ( nodeCount * 0.05f ), + 1.f + ); + node->addAnimator ( anim ); + anim->drop (); + } } } + // show name + if ( showShaderName ) + { + IBillboardTextSceneNode* node2 = 0; + swprintf ( (wchar_t*) buf, sizeof(buf) / 2, L"%hs", itemElement->key ); + node2 = smgr->addBillboardTextSceneNode( + font, + (wchar_t*) buf, + parent, + dimension2d(80.0f, 8.0f), + p + vector3df(0, 30, 0), + 0 + ); + } + } // music diff --git a/examples/21.Quake3Explorer/q3factory.h b/examples/21.Quake3Explorer/q3factory.h index b4db3e77..ccda59c4 100644 --- a/examples/21.Quake3Explorer/q3factory.h +++ b/examples/21.Quake3Explorer/q3factory.h @@ -16,6 +16,7 @@ using namespace gui; using namespace video; using namespace core; using namespace quake3; +using namespace io; @@ -48,6 +49,15 @@ enum eItemSubGroup CHAINGUN, }; +//! aplly a special effect to the shader +enum eItemSpecialEffect +{ + SPECIAL_SFX_NONE = 0, + SPECIAL_SFX_ROTATE = 1, + SPECIAL_SFX_BOUNCE = 2, + SPECIAL_SFX_ROTATE_1 = 4, +}; + // a List for defining a model struct SItemElement { @@ -59,12 +69,11 @@ struct SItemElement s32 value; eItemGroup group; eItemSubGroup sub; + u32 special; }; -/*! - Get's an entity based on it's key -*/ +//! Get's an entity based on it's key const SItemElement * getItemElement ( const stringc& key ); /*! diff --git a/examples/BuildAllExamples_v8.sln b/examples/BuildAllExamples_v8.sln index ea977559..0485a800 100644 --- a/examples/BuildAllExamples_v8.sln +++ b/examples/BuildAllExamples_v8.sln @@ -19,6 +19,9 @@ EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "07.Collision_vc8", "07.Collision\Collision_vc8.vcproj", "{3E30297B-5BE3-4A5C-B31E-08A28ADDB29E}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "08.SpecialFX_vc8", "08.SpecialFX\SpecialFX_vc8.vcproj", "{C869BF55-B9D6-4980-BC92-60FA0CF8411A}" + ProjectSection(ProjectDependencies) = postProject + {E08E042A-6C45-411B-92BE-3CC31331019F} = {E08E042A-6C45-411B-92BE-3CC31331019F} + EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "09.Meshviewer_vc8", "09.Meshviewer\Meshviewer_vc8.vcproj", "{2AE24484-22FC-481B-9A40-7CD0DA5C8E06}" EndProject @@ -29,10 +32,16 @@ EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "12.TerrainRendering_vc8", "12.TerrainRendering\TerrainRendering_vc8.vcproj", "{3A5B74E5-6390-43B0-A459-2793B81FFD31}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "13.RenderToTexture_vc8", "13.RenderToTexture\RenderToTexture_vc8.vcproj", "{0914E5C8-5352-467B-8421-C9EB35BD5596}" + ProjectSection(ProjectDependencies) = postProject + {E08E042A-6C45-411B-92BE-3CC31331019F} = {E08E042A-6C45-411B-92BE-3CC31331019F} + EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "14.Win32Window_vc8", "14.Win32Window\Win32Window_vc8.vcproj", "{772FBE05-D05A-467B-9842-BEC409EEA8D0}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "15.LoadIrrFile_vc8", "15.LoadIrrFile\LoadIrrFile_vc8.vcproj", "{78C9F424-523C-49AC-94B7-823AA4A26BF9}" + ProjectSection(ProjectDependencies) = postProject + {E08E042A-6C45-411B-92BE-3CC31331019F} = {E08E042A-6C45-411B-92BE-3CC31331019F} + EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Irrlicht", "..\source\Irrlicht\Irrlicht8.0.vcproj", "{E08E042A-6C45-411B-92BE-3CC31331019F}" EndProject diff --git a/examples/Demo/CMainMenu.cpp b/examples/Demo/CMainMenu.cpp index a56fd753..b0bc3c65 100644 --- a/examples/Demo/CMainMenu.cpp +++ b/examples/Demo/CMainMenu.cpp @@ -4,64 +4,6 @@ #include "CMainMenu.h" -//! we want the lights follow the model when it's moving -class CSceneNodeAnimatorFollowBoundingBox : public irr::scene::ISceneNodeAnimator -{ -public: - - //! constructor - CSceneNodeAnimatorFollowBoundingBox(irr::scene::ISceneNode* tofollow, - const core::vector3df &offset, u32 frequency, s32 phase) - : Offset(offset), ToFollow(tofollow), Frequency(frequency), Phase(phase) - { - if (ToFollow) - ToFollow->grab(); - } - - //! destructor - virtual ~CSceneNodeAnimatorFollowBoundingBox() - { - if (ToFollow) - ToFollow->drop(); - } - - //! animates a scene node - virtual void animateNode(irr::scene::ISceneNode* node, u32 timeMs) - { - if (0 == node || node->getType() != irr::scene::ESNT_LIGHT) - return; - - irr::scene::ILightSceneNode* l = (irr::scene::ILightSceneNode*) node; - - if (ToFollow) - { - core::vector3df now = l->getPosition(); - now += ToFollow->getBoundingBox().getCenter(); - now += Offset; - l->setPosition(now); - } - - irr::video::SColorHSL color; - irr::video::SColor rgb(0); - color.Hue = ( (timeMs + Phase) % Frequency ) * ( 2.f * irr::core::PI / Frequency ); - color.Saturation = 1.f; - color.Luminance = 0.5f; - color.toRGB(rgb); - - video::SLight light = l->getLightData(); - light.DiffuseColor = rgb; - l->setLightData(light); - } - - virtual scene::ISceneNodeAnimator* createClone(scene::ISceneNode* node, scene::ISceneManager* newManager=0) {return 0;} -private: - - core::vector3df Offset; - irr::scene::ISceneNode* ToFollow; - s32 Frequency; - s32 Phase; -}; - CMainMenu::CMainMenu() : startButton(0), MenuDevice(0), selected(2), start(false), fullscreen(true), @@ -74,7 +16,12 @@ bool CMainMenu::run(bool& outFullscreen, bool& outMusic, bool& outShadows, bool& outAdditive, bool& outVSync, bool& outAA, video::E_DRIVER_TYPE& outDriver) { - MenuDevice = createDevice(video::EDT_BURNINGSVIDEO, + //video::E_DRIVER_TYPE driverType = video::EDT_DIRECT3D9; + //video::E_DRIVER_TYPE driverType = video::EDT_OPENGL; + video::E_DRIVER_TYPE driverType = video::EDT_BURNINGSVIDEO; + //video::E_DRIVER_TYPE driverType = video::EDT_SOFTWARE; + + MenuDevice = createDevice(driverType, core::dimension2d(512, 384), 16, false, false, false, this); if (MenuDevice->getFileSystem()->existFile("irrlicht.dat")) @@ -116,7 +63,7 @@ bool CMainMenu::run(bool& outFullscreen, bool& outMusic, bool& outShadows, box->addItem(L"OpenGL 1.5"); box->addItem(L"Direct3D 8.1"); box->addItem(L"Direct3D 9.0c"); - box->addItem(L"Burning's Video 0.40"); + box->addItem(L"Burning's Video 0.42"); box->addItem(L"Irrlicht Software Renderer 1.0"); box->setSelected(selected); @@ -163,95 +110,105 @@ bool CMainMenu::run(bool& outFullscreen, bool& outMusic, bool& outShadows, modelNode->setPosition( core::vector3df(0.f, 0.f, -5.f) ); modelNode->setMaterialTexture(0, driver->getTexture("../../media/faerie2.bmp")); modelNode->setMaterialFlag(video::EMF_LIGHTING, true); - modelNode->getMaterial(0).Shininess = 28.f; - modelNode->getMaterial(0).NormalizeNormals = true; + modelNode->getMaterial(0).Shininess = 50.f; + //modelNode->getMaterial(0).NormalizeNormals = true; modelNode->setMD2Animation(scene::EMAT_STAND); } // set ambient light (no sun light in the catacombs) - smgr->setAmbientLight( video::SColorf(0.f, 0.f, 0.f) ); + smgr->setAmbientLight( video::SColorf(0.2f, 0.2f, 0.2f) ); + scene::ILightSceneNode *light; scene::ISceneNodeAnimator* anim; scene::ISceneNode* bill; - // add light 1 (sunset orange) - scene::ILightSceneNode* light1 = - smgr->addLightSceneNode(0, core::vector3df(10.f,10.f,0), - video::SColorf(0.86f, 0.38f, 0.05f), 200.0f); - - // add fly circle animator to light 1 - anim = smgr->createFlyCircleAnimator(core::vector3df(0,0,0),30.0f, -0.004f, core::vector3df(0.41f, 0.4f, 0.0f)); - light1->addAnimator(anim); - anim->drop(); - - // let the lights follow the model... - anim = new CSceneNodeAnimatorFollowBoundingBox(modelNode, core::vector3df(0,16,0), 4000, 0); - //light1->addAnimator(anim); - anim->drop(); - - // attach billboard to the light - bill = smgr->addBillboardSceneNode(light1, core::dimension2d(10, 10)); - bill->setMaterialFlag(video::EMF_LIGHTING, false); - bill->setMaterialType(video::EMT_TRANSPARENT_ADD_COLOR); - bill->setMaterialTexture(0, driver->getTexture("../../media/particlered.bmp")); - -#if 1 - // add light 2 (nearly red) - scene::ILightSceneNode* light2 = - smgr->addLightSceneNode(0, core::vector3df(0,1,0), - video::SColorf(0.9f, 1.0f, 0.f, 0.0f), 200.0f); - - // add fly circle animator to light 1 - anim = smgr->createFlyCircleAnimator(core::vector3df(0,0,0),30.0f, 0.004f, core::vector3df(0.41f, 0.4f, 0.0f)); - light2->addAnimator(anim); - anim->drop(); - - // let the lights follow the model... - anim = new CSceneNodeAnimatorFollowBoundingBox( modelNode, core::vector3df(0,-8,0), 2000, 0 ); - //light2->addAnimator(anim); - anim->drop(); - - - // attach billboard to the light - bill = smgr->addBillboardSceneNode(light2, core::dimension2d(10, 10)); - bill->setMaterialFlag(video::EMF_LIGHTING, false); - bill->setMaterialType(video::EMT_TRANSPARENT_ADD_COLOR); - bill->setMaterialTexture(0, driver->getTexture("../../media/particlered.bmp")); - - // add light 3 (nearly blue) - scene::ILightSceneNode* light3 = - smgr->addLightSceneNode(0, core::vector3df(0,-1,0), - video::SColorf(0.f, 0.0f, 0.9f, 0.0f), 40.0f); - - // add fly circle animator to light 2 - anim = smgr->createFlyCircleAnimator(core::vector3df(0,0,0),40.0f, 0.004f, core::vector3df(-0.41f, -0.4f, 0.0f)); - light3->addAnimator(anim); - anim->drop(); - - // let the lights follow the model... - anim = new CSceneNodeAnimatorFollowBoundingBox(modelNode, core::vector3df(0,8,0), 8000, 0); - //light3->addAnimator(anim); - anim->drop(); - - // attach billboard to the light - bill = smgr->addBillboardSceneNode(light3, core::dimension2d(10, 10)); - if (bill) + enum eLightParticle { - bill->setMaterialFlag(video::EMF_LIGHTING, false); - bill->setMaterialType(video::EMT_TRANSPARENT_ADD_COLOR); - bill->setMaterialTexture(0, driver->getTexture("../../media/portal1.bmp")); + LIGHT_NONE, + LIGHT_GLOBAL, + LIGHT_RED, + LIGHT_BLUE + }; + core::vector3df lightDir[2] = { + core::vector3df(0.f, 0.1f, 0.4f), + core::vector3df(0.f, 0.1f, -0.4f), + }; + + struct SLightParticle + { + eLightParticle type; + u32 dir; + }; + const SLightParticle lightParticle[] = + { + //LIGHT_GLOBAL,0, + LIGHT_RED,0, + LIGHT_BLUE,0, + LIGHT_RED,1, + LIGHT_BLUE,1, + LIGHT_NONE,0 + }; + + const SLightParticle *l = lightParticle; + while ( l->type != LIGHT_NONE ) + { + switch ( l->type ) + { + case LIGHT_GLOBAL: + // add illumination from the background + light = smgr->addLightSceneNode(0, core::vector3df(10.f,40.f,-5.f), + video::SColorf(0.2f, 0.2f, 0.2f), 90.f); + break; + case LIGHT_RED: + // add light nearly red + light = smgr->addLightSceneNode(0, core::vector3df(0,1,0), + video::SColorf(0.8f, 0.f, 0.f, 0.0f), 30.0f); + // attach red billboard to the light + bill = smgr->addBillboardSceneNode(light, core::dimension2d(10, 10)); + if ( bill ) + { + bill->setMaterialFlag(video::EMF_LIGHTING, false); + bill->setMaterialType(video::EMT_TRANSPARENT_ADD_COLOR); + bill->setMaterialTexture(0, driver->getTexture("../../media/particlered.bmp")); + } + // add fly circle animator to the light + anim = smgr->createFlyCircleAnimator(core::vector3df(0.f,0.f,-5.f),20.f, + 0.002f, lightDir [l->dir] ); + light->addAnimator(anim); + anim->drop(); + break; + case LIGHT_BLUE: + // add light nearly blue + light = smgr->addLightSceneNode(0, core::vector3df(0,1,0), + video::SColorf(0.f, 0.0f, 0.8f, 0.0f), 30.0f); + // attach blue billboard to the light + bill = smgr->addBillboardSceneNode(light, core::dimension2d(10, 10)); + if (bill) + { + bill->setMaterialFlag(video::EMF_LIGHTING, false); + bill->setMaterialType(video::EMT_TRANSPARENT_ADD_COLOR); + bill->setMaterialTexture(0, driver->getTexture("../../media/portal1.bmp")); + } + // add fly circle animator to the light + anim = smgr->createFlyCircleAnimator(core::vector3df(0.f,0.f,-5.f),20.f, + -0.002f, lightDir [l->dir], 0.5f); + light->addAnimator(anim); + anim->drop(); + break; + } + l += 1; } -#endif // create a fixed camera - smgr->addCameraSceneNode(0, core::vector3df(45,0,0), core::vector3df(0,0,10)); + scene::ICameraSceneNode* cam = smgr->addCameraSceneNode(0, core::vector3df(45,0,0), core::vector3df(0,0,10)); + // irrlicht logo and background // add irrlicht logo bool oldMipMapState = driver->getTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS); driver->setTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS, false); - guienv->addImage(driver->getTexture("../../media/irrlichtlogo2.png"), + guienv->addImage(driver->getTexture("../../media/irrlichtlogo3.png"), core::position2d(5,5)); video::ITexture* irrlichtBack = driver->getTexture("../../media/demoback.jpg"); diff --git a/include/IFileSystem.h b/include/IFileSystem.h index da3b9608..3aeb320a 100644 --- a/include/IFileSystem.h +++ b/include/IFileSystem.h @@ -88,7 +88,7 @@ public: \param ignorePaths: If set to true, files in the added archive can be accessed without its complete path. \return Returns true if the archive was added successful, false if not. */ - virtual bool registerFileArchive( const core::string& filename, bool ignoreCase = true, bool ignorePaths = true, s32 index = -1) = 0; + virtual bool registerFileArchive( const core::string& filename, bool ignoreCase = true, bool ignorePaths = true) = 0; //! Adds an external archive loader to the engine. virtual void addArchiveLoader(IArchiveLoader* loader) = 0; @@ -99,6 +99,9 @@ public: //! removes an archive from the file system. virtual bool unregisterFileArchive( u32 index ) = 0; + //! move the hirarchy of the filesystem. moves sourceIndex relative up or down + virtual bool moveFileArchive( u32 sourceIndex, s32 relative ) = 0; + //! get the Archive number index virtual IFileArchive* getFileArchive( u32 index ) = 0; diff --git a/include/IGUITable.h b/include/IGUITable.h index e85d8d39..dc976726 100644 --- a/include/IGUITable.h +++ b/include/IGUITable.h @@ -127,6 +127,9 @@ namespace gui //! Returns which row is currently selected virtual s32 getSelected() const = 0; + //! set wich row is currently selected + virtual void setSelected( s32 index ) = 0; + //! Get amount of rows in the tabcontrol virtual s32 getRowCount() const = 0; diff --git a/include/IMeshManipulator.h b/include/IMeshManipulator.h index 3f02cbfb..81a92a4f 100644 --- a/include/IMeshManipulator.h +++ b/include/IMeshManipulator.h @@ -162,6 +162,14 @@ namespace scene information. */ virtual IMesh* createMeshWith2TCoords(IMesh* mesh) const = 0; + //! Creates a copy of the mesh, which will only consist of S3DVertex vertices. + /** \param mesh Input mesh + \return Mesh consisting only of S3DVertex vertices. If + you no longer need the cloned mesh, you should call + IMesh::drop(). See IReferenceCounted::drop() for more + information. */ + virtual IMesh* createMeshWith1TCoords(IMesh* mesh) const = 0; + //! Creates a copy of a mesh with all vertices unwelded /** \param mesh Input mesh \return Mesh consisting only of unique faces. All vertices diff --git a/include/IQ3LevelMesh.h b/include/IQ3LevelMesh.h index 6dd980ea..a0008876 100644 --- a/include/IQ3LevelMesh.h +++ b/include/IQ3LevelMesh.h @@ -25,16 +25,12 @@ namespace scene \param fileNameIsValid Specifies whether the filename is valid in the current situation. */ virtual const quake3::IShader* getShader( const c8* filename, bool fileNameIsValid=true ) = 0; - virtual const quake3::IShader* getShader( const core::string& filename,bool fileNameIsValid=true ) - { - return getShader ( core::stringc ( filename ).c_str(), fileNameIsValid ); - } - //! returns a already loaded Shader virtual const quake3::IShader* getShader(u32 index) const = 0; //! get's an interface to the entities - virtual quake3::tQ3EntityList& getEntityList( const c8 * filename = 0) = 0; + virtual quake3::tQ3EntityList& getEntityList() = 0; + }; } // end namespace scene diff --git a/include/ISceneManager.h b/include/ISceneManager.h index c22da791..24a4ed8e 100644 --- a/include/ISceneManager.h +++ b/include/ISceneManager.h @@ -13,6 +13,7 @@ #include "SColor.h" #include "ETerrainElements.h" #include "ESceneNodeTypes.h" +#include "ESceneNodeAnimatorTypes.h" #include "EMeshWriterEnums.h" #include "SceneParameters.h" @@ -26,6 +27,7 @@ namespace io class IReadFile; class IAttributes; class IWriteFile; + class IFileSystem; } // end namespace io namespace gui @@ -366,6 +368,11 @@ namespace scene This pointer should not be dropped. See IReferenceCounted::drop() for more information. */ virtual gui::IGUIEnvironment* getGUIEnvironment() = 0; + //! Get the active FileSystem + /** \return Pointer to the FileSystem + This pointer should not be dropped. See IReferenceCounted::drop() for more information. */ + virtual io::IFileSystem* getFileSystem() = 0; + //! adds Volume Lighting Scene Node. /** Example Usage: scene::IVolumeLightSceneNode * n = smgr->addVolumeLightSceneNode(NULL, -1, @@ -1052,7 +1059,9 @@ namespace scene \param speed: The orbital speed, in radians per millisecond. \param direction: Specifies the upvector used for alignment of the mesh. \param startPosition: The position on the circle where the animator will - begin. Value is in multiples of a circle, i.e. 0.5 is half way around. + begin. Value is in multiples of a circle, i.e. 0.5 is half way around. (phase) + \param radiusEllipsoid: if radiusEllipsoid != 0 then radius2 froms a ellipsoid + begin. Value is in multiples of a circle, i.e. 0.5 is half way around. (phase) \return The animator. Attach it to a scene node with ISceneNode::addAnimator() and the animator will animate it. If you no longer need the animator, you should call ISceneNodeAnimator::drop(). @@ -1061,7 +1070,8 @@ namespace scene const core::vector3df& center=core::vector3df(0.f,0.f,0.f), f32 radius=100.f, f32 speed=0.001f, const core::vector3df& direction=core::vector3df(0.f, 1.f, 0.f), - f32 startPosition = 0.f) = 0; + f32 startPosition = 0.f, + f32 radiusEllipsoid = 0.f) = 0; //! Creates a fly straight animator, which lets the attached scene node fly or move along a line between two points. /** \param startPoint: Start point of the line. @@ -1075,7 +1085,7 @@ namespace scene If you no longer need the animator, you should call ISceneNodeAnimator::drop(). See IReferenceCounted::drop() for more information. */ virtual ISceneNodeAnimator* createFlyStraightAnimator(const core::vector3df& startPoint, - const core::vector3df& endPoint, u32 timeForWay, bool loop=false) = 0; + const core::vector3df& endPoint, u32 timeForWay, bool loop=false, bool pingpong = false) = 0; //! Creates a texture animator, which switches the textures of the target scene node based on a list of textures. /** \param textures: List of textures to use. @@ -1329,6 +1339,9 @@ namespace scene //! Get typename from a scene node type or null if not found virtual const c8* getSceneNodeTypeName(ESCENE_NODE_TYPE type) = 0; + //! Returns a typename from a scene node animator type or null if not found + virtual const c8* getAnimatorTypeName(ESCENE_NODE_ANIMATOR_TYPE type) = 0; + //! Adds a scene node to the scene by name /** \return Pointer to the scene node added by a factory This pointer should not be dropped. See IReferenceCounted::drop() for more information. */ diff --git a/include/ITexture.h b/include/ITexture.h index 93af6562..9745bb40 100644 --- a/include/ITexture.h +++ b/include/ITexture.h @@ -152,6 +152,7 @@ public: /** \return Returns the color format of texture. */ virtual ECOLOR_FORMAT getColorFormat() const = 0; + //! Returns pitch of texture (in bytes). /** The pitch is the amount of bytes used for a row of pixels in a texture. @@ -162,6 +163,11 @@ public: /** \return Returns true if texture has MipMaps, else false. */ virtual bool hasMipMaps() const { return false; } + //! Returns if the texture has an alpha channel + virtual bool hasAlpha() const { + return getColorFormat () == video::ECF_A8R8G8B8 || getColorFormat () == video::ECF_A1R5G5B5; + } + //! Regenerates the mip map levels of the texture. /** Required after locking and modifying the texture */ virtual void regenerateMipMapLevels() = 0; diff --git a/include/SMaterial.h b/include/SMaterial.h index a1aa69a3..9a095923 100644 --- a/include/SMaterial.h +++ b/include/SMaterial.h @@ -98,6 +98,22 @@ namespace video dstFact = E_BLEND_FACTOR ( ( state & 0x000000FF ) ); } + //! EMT_ONETEXTURE_BLEND: has BlendFactor Alphablending + inline bool textureBlendFunc_hasAlpha ( const E_BLEND_FACTOR factor ) + { + switch ( factor ) + { + case EBF_SRC_ALPHA: + case EBF_ONE_MINUS_SRC_ALPHA: + case EBF_DST_ALPHA: + case EBF_ONE_MINUS_DST_ALPHA: + case EBF_SRC_ALPHA_SATURATE: + return true; + } + return false; + } + + //! These flags are used to specify the anti-aliasing and smoothing modes /** Techniques supported are multisampling, geometry smoothing, and alpha to coverage. @@ -138,7 +154,8 @@ namespace video Shininess(0.0f), MaterialTypeParam(0.0f), MaterialTypeParam2(0.0f), Thickness(1.0f), Wireframe(false), PointCloud(false), GouraudShading(true), Lighting(true), ZWriteEnable(true), BackfaceCulling(true), FrontfaceCulling(false), - FogEnable(false), NormalizeNormals(false), ZBuffer(ECFN_LESSEQUAL), AntiAliasing(EAAM_SIMPLE|EAAM_LINE_SMOOTH), ColorMask(ECP_ALL) + FogEnable(false), NormalizeNormals(false), ZBuffer(ECFN_LESSEQUAL), + AntiAliasing(EAAM_SIMPLE|EAAM_LINE_SMOOTH), ColorMask(ECP_ALL) { } //! Copy constructor diff --git a/include/SViewFrustum.h b/include/SViewFrustum.h index f310629b..c08c0d22 100644 --- a/include/SViewFrustum.h +++ b/include/SViewFrustum.h @@ -42,14 +42,6 @@ namespace scene VF_PLANE_COUNT }; - //! Hold a copy of important transform matrices - enum E_TRANSFORMATION_STATE_3 - { - ETS_VIEW_PROJECTION_3 = video::ETS_PROJECTION + 1, - ETS_VIEW_MODEL_INVERSE_3, - ETS_CURRENT_3, - ETS_COUNT_3 - }; //! Default Constructor SViewFrustum() {} @@ -85,8 +77,11 @@ namespace scene //! recalculates the bounding box member based on the planes inline void recalculateBoundingBox(); - //! update the given state's matrix - void setTransformState( video::E_TRANSFORMATION_STATE state); + //! update the given state's matrix based on video::E_TRANSFORMATION_STATE + core::matrix4& getTransform( video::E_TRANSFORMATION_STATE state); + + //! get the given state's matrix based on frustum E_TRANSFORMATION_STATE_FRUSTUM + const core::matrix4& getTransform( video::E_TRANSFORMATION_STATE state) const; //! the position of the camera core::vector3df cameraPosition; @@ -97,11 +92,23 @@ namespace scene //! bounding box around the view frustum core::aabbox3d boundingBox; + private: //! Hold a copy of important transform matrices - core::matrix4 Matrices[ETS_COUNT_3]; + enum E_TRANSFORMATION_STATE_FRUSTUM + { + ETS_VIEW = 0, + ETS_PROJECTION = 1, + ETS_COUNT_FRUSTUM + }; + + //! Hold a copy of important transform matrices + core::matrix4 Matrices[ETS_COUNT_FRUSTUM]; }; + /*! + Copy constructor ViewFrustum + */ inline SViewFrustum::SViewFrustum(const SViewFrustum& other) { cameraPosition=other.cameraPosition; @@ -111,7 +118,7 @@ namespace scene for (i=0; i0 && Y>0) return tmp + 270; @@ -218,7 +218,7 @@ public: if (tmp == 0.0) return 90.0; - tmp = tmp / sqrt((f64)((X*X + Y*Y) * (b.X*b.X + b.Y*b.Y))); + tmp = tmp / core::squareroot((f64)((X*X + Y*Y) * (b.X*b.X + b.Y*b.Y))); if (tmp < 0.0) tmp = -tmp; diff --git a/include/vector3d.h b/include/vector3d.h index b8e09ada..95510649 100644 --- a/include/vector3d.h +++ b/include/vector3d.h @@ -87,7 +87,7 @@ namespace core vector3d& set(const vector3d& p) {X=p.X; Y=p.Y; Z=p.Z;return *this;} //! Get length of the vector. - T getLength() const { return (T) sqrt((f64)(X*X + Y*Y + Z*Z)); } + T getLength() const { return core::squareroot( X*X + Y*Y + Z*Z ); } //! Get squared length of the vector. /** This is useful because it is much faster than getLength(). @@ -146,7 +146,7 @@ namespace core return *this; length = core::reciprocal_squareroot ( (f32)length ); #else - const f32 length = core::reciprocal_squareroot ( (f32)(X*X + Y*Y + Z*Z) ); + const T length = core::reciprocal_squareroot ( (T) (X*X + Y*Y + Z*Z) ); #endif X = (T)(X * length); @@ -279,21 +279,21 @@ namespace core { vector3d angle; - angle.Y = (T)(atan2(X, Z) * RADTODEG64); + angle.Y = (T)(atan2(X, Z) * (T) RADTODEG64); if (angle.Y < 0.0f) angle.Y += 360.0f; if (angle.Y >= 360.0f) angle.Y -= 360.0f; - const f64 z1 = sqrt(X*X + Z*Z); + const T z1 = core::squareroot(X*X + Z*Z); - angle.X = (T)(atan2(z1, (f64)Y) * RADTODEG64 - 90.0); + angle.X = (T)(atan2(z1, (T)Y) * (T) RADTODEG64 - (T) 90.0); - if (angle.X < 0.0f) - angle.X += 360.0f; - if (angle.X >= 360.0f) - angle.X -= 360.0f; + if (angle.X < (T) 0.0) + angle.X += (T) 360.0; + if (angle.X >= (T) 360.0) + angle.X -= (T) 360.0; return angle; } diff --git a/source/Irrlicht/CAnimatedMeshMD3.cpp b/source/Irrlicht/CAnimatedMeshMD3.cpp index dc2b01eb..04c6c851 100644 --- a/source/Irrlicht/CAnimatedMeshMD3.cpp +++ b/source/Irrlicht/CAnimatedMeshMD3.cpp @@ -63,8 +63,7 @@ struct SMD3Shader //! Constructor CAnimatedMeshMD3::CAnimatedMeshMD3() -// TODO: Correct initial values needed -: Mesh(0), IPolShift(0), LoopMode(0), Scaling(1.f) +:Mesh(0), IPolShift(0), LoopMode(0), Scaling(1.f) { #ifdef _DEBUG setDebugName("CAnimatedMeshMD3"); @@ -73,6 +72,7 @@ CAnimatedMeshMD3::CAnimatedMeshMD3() Mesh = new SMD3Mesh(); setInterpolationShift ( 0, 0 ); + } @@ -192,7 +192,8 @@ IMesh* CAnimatedMeshMD3::getMesh(s32 frame, s32 detailLevel, s32 startFrameLoop, //! create a Irrlicht MeshBuffer for a MD3 MeshBuffer -IMeshBuffer * CAnimatedMeshMD3::createMeshBuffer(const SMD3MeshBuffer* source) +IMeshBuffer * CAnimatedMeshMD3::createMeshBuffer(const SMD3MeshBuffer* source, + io::IFileSystem* fs, video::IVideoDriver * driver) { SMeshBufferLightMap * dest = new SMeshBufferLightMap(); dest->Vertices.set_used( source->MeshHeader.numVertices ); @@ -218,6 +219,15 @@ IMeshBuffer * CAnimatedMeshMD3::createMeshBuffer(const SMD3MeshBuffer* source) v.TCoords2.X = 0.f; v.TCoords2.Y = 0.f; } + + // load static texture + u32 pos = 0; + quake3::tTexArray textureArray; + quake3::getTextures( textureArray, source->Shader, pos, fs, driver ); + dest->Material.MaterialType = video::EMT_SOLID; + dest->Material.setTexture ( 0, textureArray[0] ); + dest->Material.Lighting = false; + return dest; } @@ -284,7 +294,8 @@ void CAnimatedMeshMD3::buildTagArray ( u32 frameA, u32 frameB, f32 interpolate ) /*! loads a model */ -bool CAnimatedMeshMD3::loadModelFile( u32 modelIndex, io::IReadFile* file) +bool CAnimatedMeshMD3::loadModelFile( u32 modelIndex, io::IReadFile* file, + io::IFileSystem* fs, video::IVideoDriver * driver) { if (!file) return false; @@ -364,7 +375,7 @@ bool CAnimatedMeshMD3::loadModelFile( u32 modelIndex, io::IReadFile* file) buf->Indices.set_used ( meshHeader.numTriangles * 3 ); buf->Tex.set_used ( meshHeader.numVertices ); - //! read skins (shaders) + //! read skins (shaders). should be 1 per meshbuffer SMD3Shader skin; file->seek( offset + buf->MeshHeader.offset_shaders ); for ( s32 g = 0; g != buf->MeshHeader.numShader; ++g ) @@ -398,10 +409,11 @@ bool CAnimatedMeshMD3::loadModelFile( u32 modelIndex, io::IReadFile* file) // Init Mesh Interpolation for ( i = 0; i != Mesh->Buffer.size (); ++i ) { - IMeshBuffer * buffer = createMeshBuffer ( Mesh->Buffer[i] ); + IMeshBuffer * buffer = createMeshBuffer ( Mesh->Buffer[i], fs, driver ); MeshIPol.addMeshBuffer ( buffer ); buffer->drop (); } + MeshIPol.recalculateBoundingBox (); // Init Tag Interpolation for (i = 0; i != (u32)Mesh->MD3Header.numTags; ++i ) diff --git a/source/Irrlicht/CAnimatedMeshMD3.h b/source/Irrlicht/CAnimatedMeshMD3.h index ab6c42dc..27836eb5 100644 --- a/source/Irrlicht/CAnimatedMeshMD3.h +++ b/source/Irrlicht/CAnimatedMeshMD3.h @@ -24,13 +24,15 @@ namespace scene public: //! constructor - CAnimatedMeshMD3(); + CAnimatedMeshMD3( ); //! destructor virtual ~CAnimatedMeshMD3(); //! loads a quake3 md3 file - virtual bool loadModelFile( u32 modelIndex, io::IReadFile* file); + virtual bool loadModelFile( u32 modelIndex, io::IReadFile* file, + io::IFileSystem* fs, video::IVideoDriver * driver + ); // IAnimatedMeshMD3 virtual void setInterpolationShift ( u32 shift, u32 loopMode ); @@ -119,7 +121,7 @@ namespace scene SMesh MeshIPol; SMD3QuaternionTagList TagListIPol; - IMeshBuffer * createMeshBuffer ( const SMD3MeshBuffer *source ); + IMeshBuffer * createMeshBuffer ( const SMD3MeshBuffer *source, io::IFileSystem* fs, video::IVideoDriver * driver ); void buildVertexArray ( u32 frameA, u32 frameB, f32 interpolate, const SMD3MeshBuffer * source, @@ -127,7 +129,6 @@ namespace scene ); void buildTagArray ( u32 frameA, u32 frameB, f32 interpolate ); - }; diff --git a/source/Irrlicht/CBSPMeshFileLoader.cpp b/source/Irrlicht/CBSPMeshFileLoader.cpp index e541f052..f3c62b33 100644 --- a/source/Irrlicht/CBSPMeshFileLoader.cpp +++ b/source/Irrlicht/CBSPMeshFileLoader.cpp @@ -51,7 +51,7 @@ bool CBSPMeshFileLoader::isALoadableFileExtension(const core::string& filen IAnimatedMesh* CBSPMeshFileLoader::createMesh(io::IReadFile* file) { s32 type = core::isFileExtension ( file->getFileName(), "bsp", "shader", "cfg" ); - IQ3LevelMesh* q = 0; + CQ3LevelMesh* q = 0; switch ( type ) { @@ -70,7 +70,7 @@ IAnimatedMesh* CBSPMeshFileLoader::createMesh(io::IReadFile* file) //q->getShader("scripts/sky.shader"); } - if ( ((CQ3LevelMesh*)q)->loadFile(file) ) + if ( q->loadFile(file) ) return q; q->drop(); @@ -78,15 +78,22 @@ IAnimatedMesh* CBSPMeshFileLoader::createMesh(io::IReadFile* file) case 2: q = new CQ3LevelMesh(FileSystem, SceneManager,LoadParam); - q->getShader( file->getFileName() ); + q->getShader( file ); return q; break; + case 3: // load quake 3 loading parameter if ( file->getFileName() == "levelparameter.cfg" ) { file->read ( &LoadParam, sizeof ( LoadParam ) ); } + else + { + q = new CQ3LevelMesh(FileSystem, SceneManager,LoadParam); + q->getConfiguration( file ); + return q; + } break; } diff --git a/source/Irrlicht/CCameraSceneNode.cpp b/source/Irrlicht/CCameraSceneNode.cpp index 25865fa9..09bfdd18 100644 --- a/source/Irrlicht/CCameraSceneNode.cpp +++ b/source/Irrlicht/CCameraSceneNode.cpp @@ -61,8 +61,7 @@ to build a projection matrix. e.g: core::matrix4::buildProjectionMatrixPerspecti void CCameraSceneNode::setProjectionMatrix(const core::matrix4& projection, bool isOrthogonal) { IsOrthogonal = isOrthogonal; - ViewArea.Matrices [ video::ETS_PROJECTION ] = projection; - ViewArea.setTransformState ( video::ETS_PROJECTION ); + ViewArea.getTransform ( video::ETS_PROJECTION ) = projection; } @@ -70,7 +69,7 @@ void CCameraSceneNode::setProjectionMatrix(const core::matrix4& projection, bool //! \return Returns the current projection matrix of the camera. const core::matrix4& CCameraSceneNode::getProjectionMatrix() const { - return ViewArea.Matrices [ video::ETS_PROJECTION ]; + return ViewArea.getTransform ( video::ETS_PROJECTION ); } @@ -78,7 +77,7 @@ const core::matrix4& CCameraSceneNode::getProjectionMatrix() const //! \return Returns the current view matrix of the camera. const core::matrix4& CCameraSceneNode::getViewMatrix() const { - return ViewArea.Matrices [ video::ETS_VIEW ]; + return ViewArea.getTransform ( video::ETS_VIEW ); } @@ -211,8 +210,7 @@ void CCameraSceneNode::setFOV(f32 f) void CCameraSceneNode::recalculateProjectionMatrix() { - ViewArea.Matrices [ video::ETS_PROJECTION ].buildProjectionMatrixPerspectiveFovLH(Fovy, Aspect, ZNear, ZFar); - ViewArea.setTransformState ( video::ETS_PROJECTION ); + ViewArea.getTransform ( video::ETS_PROJECTION ).buildProjectionMatrixPerspectiveFovLH(Fovy, Aspect, ZNear, ZFar); } @@ -235,8 +233,7 @@ void CCameraSceneNode::OnRegisterSceneNode() up.X += 0.5f; } - ViewArea.Matrices[video::ETS_VIEW].buildCameraLookAtMatrixLH(pos, Target, up); - ViewArea.setTransformState(video::ETS_VIEW); + ViewArea.getTransform( video::ETS_VIEW ).buildCameraLookAtMatrixLH(pos, Target, up); recalculateViewArea(); if ( SceneManager->getActiveCamera () == this ) @@ -252,8 +249,8 @@ void CCameraSceneNode::render() video::IVideoDriver* driver = SceneManager->getVideoDriver(); if ( driver) { - driver->setTransform(video::ETS_PROJECTION, ViewArea.Matrices [ video::ETS_PROJECTION ] ); - driver->setTransform(video::ETS_VIEW, ViewArea.Matrices [ video::ETS_VIEW ] ); + driver->setTransform(video::ETS_PROJECTION, ViewArea.getTransform ( video::ETS_PROJECTION) ); + driver->setTransform(video::ETS_VIEW, ViewArea.getTransform ( video::ETS_VIEW) ); } } @@ -275,7 +272,12 @@ const SViewFrustum* CCameraSceneNode::getViewFrustum() const void CCameraSceneNode::recalculateViewArea() { ViewArea.cameraPosition = getAbsolutePosition(); - ViewArea.setFrom(ViewArea.Matrices[SViewFrustum::ETS_VIEW_PROJECTION_3]); + + core::matrix4 m ( core::matrix4::EM4CONST_NOTHING ); + m.setbyproduct_nocheck ( ViewArea.getTransform (video::ETS_PROJECTION), + ViewArea.getTransform (video::ETS_VIEW) + ); + ViewArea.setFrom(m); } diff --git a/source/Irrlicht/CD3D8MaterialRenderer.h b/source/Irrlicht/CD3D8MaterialRenderer.h index c3fd8573..e048ab84 100644 --- a/source/Irrlicht/CD3D8MaterialRenderer.h +++ b/source/Irrlicht/CD3D8MaterialRenderer.h @@ -98,7 +98,7 @@ public: pID3DDevice->SetTextureStageState (0, D3DTSS_COLORARG1, D3DTA_TEXTURE); pID3DDevice->SetTextureStageState (0, D3DTSS_COLORARG2, D3DTA_DIFFUSE); - if ( getTexelAlpha ( srcFact ) + getTexelAlpha ( dstFact ) ) + if ( textureBlendFunc_hasAlpha ( srcFact ) + textureBlendFunc_hasAlpha ( dstFact ) ) { pID3DDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1 ); pID3DDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE ); @@ -138,20 +138,6 @@ public: return r; } - u32 getTexelAlpha ( E_BLEND_FACTOR factor ) const - { - u32 r = 0; - switch ( factor ) - { - case EBF_SRC_ALPHA: r = 1; break; - case EBF_ONE_MINUS_SRC_ALPHA: r = 1; break; - case EBF_DST_ALPHA: r = 1; break; - case EBF_ONE_MINUS_DST_ALPHA: r = 1; break; - case EBF_SRC_ALPHA_SATURATE: r = 1; break; - } - return r; - } - u32 getD3DModulate ( E_MODULATE_FUNC func ) const { u32 r = D3DTOP_MODULATE; diff --git a/source/Irrlicht/CD3D9MaterialRenderer.h b/source/Irrlicht/CD3D9MaterialRenderer.h index ca65eb38..5daf6655 100644 --- a/source/Irrlicht/CD3D9MaterialRenderer.h +++ b/source/Irrlicht/CD3D9MaterialRenderer.h @@ -116,7 +116,7 @@ public: pID3DDevice->SetTextureStageState (0, D3DTSS_COLORARG1, D3DTA_TEXTURE); pID3DDevice->SetTextureStageState (0, D3DTSS_COLORARG2, D3DTA_DIFFUSE); - if ( getTexelAlpha ( srcFact ) + getTexelAlpha ( dstFact ) ) + if ( textureBlendFunc_hasAlpha ( srcFact ) + textureBlendFunc_hasAlpha ( dstFact ) ) { pID3DDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1 ); pID3DDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE ); @@ -156,20 +156,6 @@ public: return r; } - u32 getTexelAlpha ( E_BLEND_FACTOR factor ) const - { - u32 r = 0; - switch ( factor ) - { - case EBF_SRC_ALPHA: r = 1; break; - case EBF_ONE_MINUS_SRC_ALPHA: r = 1; break; - case EBF_DST_ALPHA: r = 1; break; - case EBF_ONE_MINUS_DST_ALPHA: r = 1; break; - case EBF_SRC_ALPHA_SATURATE: r = 1; break; - } - return r; - } - u32 getD3DModulate ( E_MODULATE_FUNC func ) const { u32 r = D3DTOP_MODULATE; diff --git a/source/Irrlicht/CFileSystem.cpp b/source/Irrlicht/CFileSystem.cpp index b98290d0..dfccbdae 100644 --- a/source/Irrlicht/CFileSystem.cpp +++ b/source/Irrlicht/CFileSystem.cpp @@ -128,14 +128,36 @@ void CFileSystem::addArchiveLoader(IArchiveLoader* loader) } +//! move the hirarchy of the filesystem. moves sourceIndex relative up or down +bool CFileSystem::moveFileArchive( u32 sourceIndex, s32 relative ) +{ + bool r = false; + const s32 dest = (s32) sourceIndex + relative; + const s32 dir = relative < 0 ? -1 : 1; + const s32 sourceEnd = ((s32) FileArchive.size() ) - 1; + IFileArchive *t; + + for ( s32 s = (s32) sourceIndex;s != dest; s += dir ) + { + if ( s < 0 || s > sourceEnd || s + dir < 0 || s + dir > sourceEnd ) + continue; + + t = FileArchive [ s + dir ]; + FileArchive [ s + dir ] = FileArchive [ s ]; + FileArchive [ s ] = t; + r = true; + } + return r; +} + //! Adds an archive to the file system. -bool CFileSystem::registerFileArchive( const core::string& filename, bool ignoreCase, bool ignorePaths, s32 index ) +bool CFileSystem::registerFileArchive( const core::string& filename, bool ignoreCase, bool ignorePaths ) { IFileArchive* archive = 0; bool ret = false; u32 i; - // try to load arhive based on file name + // try to load archive based on file name for ( i = 0; i < ArchiveLoader.size(); ++i) { if ( ArchiveLoader[i]->isALoadableFileFormat( filename ) ) @@ -148,11 +170,7 @@ bool CFileSystem::registerFileArchive( const core::string& filename, bool i if ( archive ) { - if ( index < 0 ) - FileArchive.push_back ( archive ); - else - FileArchive.insert ( archive, index ); - + FileArchive.push_back ( archive ); ret = true; } else diff --git a/source/Irrlicht/CFileSystem.h b/source/Irrlicht/CFileSystem.h index d3e4e7a4..85dbf9cd 100644 --- a/source/Irrlicht/CFileSystem.h +++ b/source/Irrlicht/CFileSystem.h @@ -43,7 +43,10 @@ public: virtual IWriteFile* createAndWriteFile(const core::string& filename, bool append=false); //! Adds an archive to the file system. - virtual bool registerFileArchive( const core::string& filename, bool ignoreCase = true, bool ignorePaths = true, s32 index = -1); + virtual bool registerFileArchive( const core::string& filename, bool ignoreCase = true, bool ignorePaths = true); + + //! move the hirarchy of the filesystem. moves sourceIndex relative up or down + virtual bool moveFileArchive( u32 sourceIndex, s32 relative ); //! Adds an external archive loader to the engine. virtual void addArchiveLoader(IArchiveLoader* loader); diff --git a/source/Irrlicht/CGUIFont.cpp b/source/Irrlicht/CGUIFont.cpp index 7df5a29c..bcab0520 100644 --- a/source/Irrlicht/CGUIFont.cpp +++ b/source/Irrlicht/CGUIFont.cpp @@ -267,12 +267,17 @@ bool CGUIFont::loadTexture(video::IImage* image, const core::string& name) if ( ret ) { - bool current = Driver->getTextureCreationFlag ( video::ETCF_ALLOW_NON_POWER_2 ); + bool flag[2]; + flag[0] = Driver->getTextureCreationFlag ( video::ETCF_ALLOW_NON_POWER_2 ); + flag[1] = Driver->getTextureCreationFlag ( video::ETCF_CREATE_MIP_MAPS ); + Driver->setTextureCreationFlag(video::ETCF_ALLOW_NON_POWER_2, true); + Driver->setTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS, false ); SpriteBank->addTexture(Driver->addTexture(name, tmpImage)); - Driver->setTextureCreationFlag(video::ETCF_ALLOW_NON_POWER_2, current ); + Driver->setTextureCreationFlag(video::ETCF_ALLOW_NON_POWER_2, flag[0] ); + Driver->setTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS, flag[1] ); } if (deleteTmpImage) tmpImage->drop(); diff --git a/source/Irrlicht/CGUIScrollBar.cpp b/source/Irrlicht/CGUIScrollBar.cpp index d7b7df22..0f023b2e 100644 --- a/source/Irrlicht/CGUIScrollBar.cpp +++ b/source/Irrlicht/CGUIScrollBar.cpp @@ -143,6 +143,8 @@ bool CGUIScrollBar::OnEvent(const SEvent& event) if (Environment->hasFocus(this)) { // thanks to a bug report by REAPER + // thanks to tommi by tommi for another bugfix + // everybody needs a little thanking. hallo niko!;-) setPos( getPos() + ( (s32)event.MouseInput.Wheel * SmallStep * (Horizontal ? 1 : -1 ) ) ); diff --git a/source/Irrlicht/CGUITable.cpp b/source/Irrlicht/CGUITable.cpp index 0e2b22d8..0bf7f2e5 100644 --- a/source/Irrlicht/CGUITable.cpp +++ b/source/Irrlicht/CGUITable.cpp @@ -377,11 +377,21 @@ void CGUITable::clearRows() } +/*! +*/ s32 CGUITable::getSelected() const { return Selected; } +//! set wich row is currently selected +void CGUITable::setSelected( s32 index ) +{ + Selected = -1; + if ( index >= 0 && index < (s32) Rows.size() ) + Selected = index; +} + void CGUITable::recalculateWidths() { diff --git a/source/Irrlicht/CGUITable.h b/source/Irrlicht/CGUITable.h index bb2d91d9..86c221fa 100644 --- a/source/Irrlicht/CGUITable.h +++ b/source/Irrlicht/CGUITable.h @@ -73,6 +73,9 @@ namespace gui //! Returns which row is currently selected virtual s32 getSelected() const; + //! set wich row is currently selected + virtual void setSelected( s32 index ); + //! Returns amount of rows in the tabcontrol virtual s32 getRowCount() const; diff --git a/source/Irrlicht/CLightSceneNode.cpp b/source/Irrlicht/CLightSceneNode.cpp index c069f36a..6e3eb7f9 100644 --- a/source/Irrlicht/CLightSceneNode.cpp +++ b/source/Irrlicht/CLightSceneNode.cpp @@ -177,6 +177,7 @@ bool CLightSceneNode::getCastShadow() const void CLightSceneNode::doLightRecalc() { + //LightData.Type = video::ELT_DIRECTIONAL; if ((LightData.Type == video::ELT_SPOT) || (LightData.Type == video::ELT_DIRECTIONAL)) { LightData.Direction = core::vector3df(.0f,.0f,1.0f); diff --git a/source/Irrlicht/CMD3MeshFileLoader.cpp b/source/Irrlicht/CMD3MeshFileLoader.cpp index aa27fcf1..d6c1febc 100644 --- a/source/Irrlicht/CMD3MeshFileLoader.cpp +++ b/source/Irrlicht/CMD3MeshFileLoader.cpp @@ -14,6 +14,17 @@ namespace irr namespace scene { +//! Constructor +CMD3MeshFileLoader::CMD3MeshFileLoader( scene::ISceneManager* smgr) +: SceneManager(smgr) +{ +} + +//! destructor +CMD3MeshFileLoader::~CMD3MeshFileLoader() +{ +} + //! returns true if the file maybe is able to be loaded by this class //! based on the file extension (e.g. ".bsp") bool CMD3MeshFileLoader::isALoadableFileExtension(const core::string& filename) const @@ -26,7 +37,7 @@ IAnimatedMesh* CMD3MeshFileLoader::createMesh(io::IReadFile* file) { CAnimatedMeshMD3 * mesh = new CAnimatedMeshMD3(); - if ( mesh->loadModelFile ( 0, file ) ) + if ( mesh->loadModelFile ( 0, file, SceneManager->getFileSystem(), SceneManager->getVideoDriver() ) ) return mesh; mesh->drop (); diff --git a/source/Irrlicht/CMD3MeshFileLoader.h b/source/Irrlicht/CMD3MeshFileLoader.h index f3358d81..9089c787 100644 --- a/source/Irrlicht/CMD3MeshFileLoader.h +++ b/source/Irrlicht/CMD3MeshFileLoader.h @@ -6,6 +6,10 @@ #define __C_MD3_MESH_FILE_LOADER_H_INCLUDED__ #include "IMeshLoader.h" +#include "IFileSystem.h" +#include "IVideoDriver.h" +#include "ISceneManager.h" +#include "IQ3Shader.h" namespace irr { @@ -17,6 +21,12 @@ class CMD3MeshFileLoader : public IMeshLoader { public: + //! Constructor + CMD3MeshFileLoader( scene::ISceneManager* smgr ); + + //! destructor + virtual ~CMD3MeshFileLoader(); + //! 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 core::string& filename) const; @@ -27,6 +37,10 @@ public: //! See IReferenceCounted::drop() for more information. virtual IAnimatedMesh* createMesh(io::IReadFile* file); +private: + io::IFileSystem* FileSystem; + scene::ISceneManager* SceneManager; + }; } // end namespace scene diff --git a/source/Irrlicht/CMeshManipulator.cpp b/source/Irrlicht/CMeshManipulator.cpp index 3b3fd3ee..641bcdff 100644 --- a/source/Irrlicht/CMeshManipulator.cpp +++ b/source/Irrlicht/CMeshManipulator.cpp @@ -812,13 +812,16 @@ IMesh* CMeshManipulator::createMeshWithTangents(IMesh* mesh, bool recalculateNor for (u32 i=0; iIndices[i] = i; - buffer->setBoundingBox(mesh->getMeshBuffer(b)->getBoundingBox()); + //buffer->setBoundingBox(mesh->getMeshBuffer(b)->getBoundingBox()); + buffer->recalculateBoundingBox (); + // add new buffer clone->addMeshBuffer(buffer); buffer->drop(); } - clone->BoundingBox = mesh->getBoundingBox(); + clone->recalculateBoundingBox (); + //clone->BoundingBox = mesh->getBoundingBox(); // now calculate tangents for (b=0; bVertices.push_back( video::S3DVertex2TCoords( - v[idx[i]].Pos, v[idx[i]].Color, v[idx[i]].TCoords, v[idx[i]].TCoords)); + v[idx[i]].Pos, v[idx[i]].Normal, v[idx[i]].Color, v[idx[i]].TCoords, v[idx[i]].TCoords)); } break; case video::EVT_2TCOORDS: @@ -1028,7 +1031,7 @@ IMesh* CMeshManipulator::createMeshWith2TCoords(IMesh* mesh) const for (u32 i=0; iVertices.push_back(video::S3DVertex2TCoords( - v[idx[i]].Pos, v[idx[i]].Color, v[idx[i]].TCoords, v[idx[i]].TCoords)); + v[idx[i]].Pos, v[idx[i]].Normal, v[idx[i]].Color, v[idx[i]].TCoords, v[idx[i]].TCoords)); } break; } @@ -1039,13 +1042,96 @@ IMesh* CMeshManipulator::createMeshWith2TCoords(IMesh* mesh) const for (u32 i=0; iIndices[i] = i; - buffer->setBoundingBox(mesh->getMeshBuffer(b)->getBoundingBox()); + //buffer->setBoundingBox(mesh->getMeshBuffer(b)->getBoundingBox()); + buffer->recalculateBoundingBox (); + // add new buffer clone->addMeshBuffer(buffer); buffer->drop(); } - clone->BoundingBox = mesh->getBoundingBox(); + clone->recalculateBoundingBox (); + //clone->BoundingBox = mesh->getBoundingBox(); + + return clone; +} + +//! Creates a copy of the mesh, which will only consist of S3DVertex vertices. +IMesh* CMeshManipulator::createMeshWith1TCoords(IMesh* mesh) const +{ + if (!mesh) + return 0; + + // copy mesh and fill data into SMeshBuffer + SMesh* clone = new SMesh(); + const u32 meshBufferCount = mesh->getMeshBufferCount(); + u32 b; + + for (b=0; bgetMeshBuffer(b)->getIndexCount(); + const u16* idx = mesh->getMeshBuffer(b)->getIndices(); + + SMeshBuffer* buffer = new SMeshBuffer(); + buffer->Material = mesh->getMeshBuffer(b)->getMaterial(); + buffer->Material.MaterialType = video::EMT_SOLID; + + // copy vertices + + buffer->Vertices.reallocate(idxCnt); + switch(mesh->getMeshBuffer(b)->getVertexType()) + { + case video::EVT_STANDARD: + { + video::S3DVertex* v = + (video::S3DVertex*)mesh->getMeshBuffer(b)->getVertices(); + + for (u32 i=0; iVertices.push_back(v[idx[i]]); + + } + break; + case video::EVT_2TCOORDS: + { + video::S3DVertex2TCoords* v = + (video::S3DVertex2TCoords*)mesh->getMeshBuffer(b)->getVertices(); + + for (u32 i=0; iVertices.push_back( + video::S3DVertex( + v[idx[i]].Pos, v[idx[i]].Normal, v[idx[i]].Color, v[idx[i]].TCoords)); + + } + break; + case video::EVT_TANGENTS: + { + video::S3DVertexTangents* v = + (video::S3DVertexTangents*)mesh->getMeshBuffer(b)->getVertices(); + + for (u32 i=0; iVertices.push_back( + video::S3DVertex( + v[idx[i]].Pos, v[idx[i]].Normal, v[idx[i]].Color, v[idx[i]].TCoords)); + } + break; + } + + // create new indices + + buffer->Indices.set_used(idxCnt); + for (u32 i=0; iIndices[i] = i; + + //buffer->setBoundingBox(mesh->getMeshBuffer(b)->getBoundingBox()); + buffer->recalculateBoundingBox (); + + // add new buffer + clone->addMeshBuffer(buffer); + buffer->drop(); + } + + clone->recalculateBoundingBox (); + //clone->BoundingBox = mesh->getBoundingBox(); return clone; } diff --git a/source/Irrlicht/CMeshManipulator.h b/source/Irrlicht/CMeshManipulator.h index 393d9eed..ff647571 100644 --- a/source/Irrlicht/CMeshManipulator.h +++ b/source/Irrlicht/CMeshManipulator.h @@ -97,6 +97,9 @@ public: //! Creates a copy of the mesh, which will only consist of S3D2TCoords vertices. virtual IMesh* createMeshWith2TCoords(IMesh* mesh) const; + //! Creates a copy of the mesh, which will only consist of S3DVertex vertices. + virtual IMesh* createMeshWith1TCoords(IMesh* mesh) const; + //! Creates a copy of the mesh, which will only consist of unique triangles, i.e. no vertices are shared. virtual IMesh* createMeshUniquePrimitives(IMesh* mesh) const; diff --git a/source/Irrlicht/COctTreeSceneNode.cpp b/source/Irrlicht/COctTreeSceneNode.cpp index 29a24aac..2fd575f6 100644 --- a/source/Irrlicht/COctTreeSceneNode.cpp +++ b/source/Irrlicht/COctTreeSceneNode.cpp @@ -109,16 +109,20 @@ void COctTreeSceneNode::render() core::matrix4 invTrans(AbsoluteTransformation, core::matrix4::EM4CONST_INVERSE); frust.transform(invTrans); } - /* - //const core::aabbox3d &box = frust.getBoundingBox(); - */ + +#if defined ( OCTTREE_BOX_BASED ) + const core::aabbox3d &box = frust.getBoundingBox(); +#endif switch(vertexType) { case video::EVT_STANDARD: { - //StdOctTree->calculatePolys(box); +#if defined ( OCTTREE_BOX_BASED ) + StdOctTree->calculatePolys(box); +#else StdOctTree->calculatePolys(frust); +#endif const OctTree::SIndexData* d = StdOctTree->getIndexData(); @@ -163,9 +167,11 @@ void COctTreeSceneNode::render() break; case video::EVT_2TCOORDS: { - //LightMapOctTree->calculatePolys(box); +#if defined ( OCTTREE_BOX_BASED ) + LightMapOctTree->calculatePolys(box); +#else LightMapOctTree->calculatePolys(frust); - +#endif const OctTree::SIndexData* d = LightMapOctTree->getIndexData(); for (u32 i=0; icalculatePolys(box); +#if defined ( OCTTREE_BOX_BASED ) + TangentsOctTree->calculatePolys(box); +#else TangentsOctTree->calculatePolys(frust); +#endif const OctTree::SIndexData* d = TangentsOctTree->getIndexData(); diff --git a/source/Irrlicht/COpenGLMaterialRenderer.h b/source/Irrlicht/COpenGLMaterialRenderer.h index 788f7f38..cd7067f7 100644 --- a/source/Irrlicht/COpenGLMaterialRenderer.h +++ b/source/Irrlicht/COpenGLMaterialRenderer.h @@ -135,7 +135,7 @@ public: glAlphaFunc(GL_GREATER, 0.f); glEnable(GL_BLEND); - if ( getTexelAlpha(srcFact) || getTexelAlpha(dstFact) ) + if ( textureBlendFunc_hasAlpha(srcFact) || textureBlendFunc_hasAlpha(dstFact) ) { glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_EXT, GL_REPLACE); glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_EXT, GL_TEXTURE); @@ -177,20 +177,6 @@ public: return r; } - u32 getTexelAlpha ( E_BLEND_FACTOR factor ) const - { - u32 r; - switch ( factor ) - { - case EBF_SRC_ALPHA: r = 1; break; - case EBF_ONE_MINUS_SRC_ALPHA: r = 1; break; - case EBF_DST_ALPHA: r = 1; break; - case EBF_ONE_MINUS_DST_ALPHA: r = 1; break; - case EBF_SRC_ALPHA_SATURATE: r = 1; break; - default: r = 0; break; - } - return r; - } }; diff --git a/source/Irrlicht/CParticleSystemSceneNode.cpp b/source/Irrlicht/CParticleSystemSceneNode.cpp index 552d744d..c9ebd662 100644 --- a/source/Irrlicht/CParticleSystemSceneNode.cpp +++ b/source/Irrlicht/CParticleSystemSceneNode.cpp @@ -315,7 +315,7 @@ void CParticleSystemSceneNode::render() #else - const core::matrix4 &m = camera->getViewFrustum()->Matrices [ video::ETS_VIEW ]; + const core::matrix4 &m = camera->getViewFrustum()->getTransform( video::ETS_VIEW ); const core::vector3df view ( -m[2], -m[6] , -m[10] ); diff --git a/source/Irrlicht/CQ3LevelMesh.cpp b/source/Irrlicht/CQ3LevelMesh.cpp index ade9589e..11660b0b 100644 --- a/source/Irrlicht/CQ3LevelMesh.cpp +++ b/source/Irrlicht/CQ3LevelMesh.cpp @@ -437,6 +437,16 @@ inline bool isQ3WhiteSpace( const u8 symbol ) return symbol == ' ' || symbol == '\t' || symbol == '\r'; } +/*! +*/ +inline bool isQ3ValidName( const u8 symbol ) +{ + return (symbol >= 'a' && symbol <= 'z' ) || + (symbol >= 'A' && symbol <= 'Z' ) || + (symbol >= '0' && symbol <= '9' ) || + (symbol == '/' || symbol == '_' || symbol == '.' ); +} + /*! */ void CQ3LevelMesh::parser_nextToken() @@ -537,7 +547,7 @@ void CQ3LevelMesh::parser_nextToken() Parser.token.append( symbol ); // continue till whitespace - bool notisWhite = true; + bool validName = true; do { if ( Parser.index >= Parser.sourcesize ) @@ -547,15 +557,13 @@ void CQ3LevelMesh::parser_nextToken() } symbol = Parser.source [ Parser.index ]; - notisWhite = ! isQ3WhiteSpace( symbol ); - if ( notisWhite ) + validName = isQ3ValidName( symbol ); + if ( validName ) { Parser.token.append( symbol ); + Parser.index += 1; } - - Parser.index += 1; - - } while ( notisWhite ); + } while ( validName ); Parser.tokenresult = Q3_TOKEN_TOKEN; return; @@ -639,7 +647,7 @@ void CQ3LevelMesh::parser_parse( const void * data, const u32 size, CQ3LevelMesh // close tag for first if ( active == 1 ) { - (this->*callback)( groupList ); + (this->*callback)( groupList, Q3_TOKEN_END_LIST ); // new group groupList->drop(); @@ -657,6 +665,8 @@ void CQ3LevelMesh::parser_parse( const void * data, const u32 size, CQ3LevelMesh } while ( Parser.tokenresult != Q3_TOKEN_EOF ); + (this->*callback)( groupList, Q3_TOKEN_EOF ); + groupList->drop(); } @@ -1354,16 +1364,49 @@ void CQ3LevelMesh::createCurvedSurface_bezier(SMeshBufferLightMap* meshBuffer, +/*! + Loads entities from file +*/ +void CQ3LevelMesh::getConfiguration( io::IReadFile* file ) +{ + tBSPLump l; + l.offset = file->getPos(); + l.length = file->getSize (); + + core::array entity; + entity.set_used( l.length + 2 ); + entity[l.length + 1 ] = 0; + + file->seek(l.offset); + file->read( entity.pointer(), l.length); + + parser_parse( entity.pointer(), l.length, &CQ3LevelMesh::scriptcallback_config ); + + if ( Entity.size () ) + Entity.getLast().name = file->getFileName(); +} + +// entity only has only one valid level.. and no assoziative name.. +void CQ3LevelMesh::scriptcallback_config( SVarGroupList *& grouplist, eToken token ) +{ + if ( token == Q3_TOKEN_END_LIST || 0 == grouplist->VariableGroup[0].Variable.size () ) + return; + + grouplist->grab(); + + SEntity element; + element.VarGroup = grouplist; + element.id = Entity.size(); + element.name = "configuration"; + + Entity.push_back( element ); +} + //! get's an interface to the entities -tQ3EntityList & CQ3LevelMesh::getEntityList( const c8 * fileName ) +tQ3EntityList & CQ3LevelMesh::getEntityList() { - if ( fileName ) - { - } - - Entity.sort(); - +// Entity.sort(); return Entity; } @@ -1450,16 +1493,39 @@ const IShader* CQ3LevelMesh::getShader( const c8 * filename, bool fileNameIsVali return 0; } - io::IReadFile *file = FileSystem->createAndOpenFile( loadFile.c_str() ); - if ( 0 == file ) - return 0; - if ( LoadParam.verbose ) { message = loadFile + " for " + searchName; os::Printer::log("quake3:getShader Load shader", message.c_str(), ELL_INFORMATION); } + + io::IReadFile *file = FileSystem->createAndOpenFile( loadFile.c_str() ); + if ( file ) + { + getShader ( file ); + if ( LoadParam.verbose > 1 ) + { + message = searchName + " found " + Shader[index].name; + os::Printer::log("quake3:getShader", message.c_str(), ELL_INFORMATION); + } + file->drop (); + } + + + // search again + index = Shader.linear_search( search ); + return index >= 0 ? &Shader[index] : 0; +} + +/*! + loads the shader definition +*/ +void CQ3LevelMesh::getShader( io::IReadFile* file ) +{ + if ( 0 == file ) + return; + // load script core::array script; const long len = file->getSize(); @@ -1468,27 +1534,10 @@ const IShader* CQ3LevelMesh::getShader( const c8 * filename, bool fileNameIsVali file->seek( 0 ); file->read( script.pointer(), len ); - file->drop(); - script[ len + 1 ] = 0; // start a parser instance parser_parse( script.pointer(), len, &CQ3LevelMesh::scriptcallback_shader ); - - // search again - index = Shader.linear_search( search ); - if ( index >= 0 ) - { - if ( LoadParam.verbose > 1 ) - { - message = searchName + " found " + Shader[index].name; - os::Printer::log("quake3:getShader", message.c_str(), ELL_INFORMATION); - } - - return &Shader[index]; - } - - return 0; } @@ -1572,9 +1621,9 @@ void CQ3LevelMesh::ReleaseEntity() // entity only has only one valid level.. and no assoziative name.. -void CQ3LevelMesh::scriptcallback_entity( SVarGroupList *& grouplist ) +void CQ3LevelMesh::scriptcallback_entity( SVarGroupList *& grouplist, eToken token ) { - if ( grouplist->VariableGroup.size() != 2 ) + if ( token != Q3_TOKEN_END_LIST || grouplist->VariableGroup.size() != 2 ) return; grouplist->grab(); @@ -1590,8 +1639,11 @@ void CQ3LevelMesh::scriptcallback_entity( SVarGroupList *& grouplist ) //!. script callback for shaders -void CQ3LevelMesh::scriptcallback_shader( SVarGroupList *& grouplist ) +void CQ3LevelMesh::scriptcallback_shader( SVarGroupList *& grouplist,eToken token ) { + if ( token != Q3_TOKEN_END_LIST ) + return; + // TODO: There might be something wrong with this fix, but it avoids a core dump... if (grouplist->VariableGroup[0].Variable.size()==0) return; @@ -1603,7 +1655,11 @@ void CQ3LevelMesh::scriptcallback_shader( SVarGroupList *& grouplist ) element.VarGroup = grouplist; element.name = element.VarGroup->VariableGroup[0].Variable[0].name; element.id = Shader.size(); - +/* + core::stringc s; + dumpShader ( s, &element ); + printf ( s.c_str () ); +*/ Shader.push_back( element ); } diff --git a/source/Irrlicht/CQ3LevelMesh.h b/source/Irrlicht/CQ3LevelMesh.h index 42bef61d..6bd83824 100644 --- a/source/Irrlicht/CQ3LevelMesh.h +++ b/source/Irrlicht/CQ3LevelMesh.h @@ -56,6 +56,9 @@ namespace scene //! Returns the type of the animated mesh. virtual E_ANIMATED_MESH_TYPE getMeshType() const; + //! loads the shader definition + virtual void getShader( io::IReadFile* file ); + //! loads the shader definition virtual const quake3::IShader * getShader( const c8 * filename, bool fileNameIsValid=true ); @@ -63,8 +66,10 @@ namespace scene virtual const quake3::IShader * getShader( u32 index ) const; + //! loads a configuration file + virtual void getConfiguration( io::IReadFile* file ); //! get's an interface to the entities - virtual quake3::tQ3EntityList & getEntityList( const c8 * fileName ); + virtual quake3::tQ3EntityList & getEntityList(); //Link to held meshes? ... @@ -419,17 +424,20 @@ namespace scene SQ3Parser Parser; - typedef void( CQ3LevelMesh::*tParserCallback ) ( quake3::SVarGroupList *& groupList ); + typedef void( CQ3LevelMesh::*tParserCallback ) ( quake3::SVarGroupList *& groupList, eToken token ); void parser_parse( const void * data, u32 size, tParserCallback callback ); void parser_nextToken(); void dumpVarGroup( const quake3::SVarGroup * group, s32 stack ) const; - void scriptcallback_entity( quake3::SVarGroupList *& grouplist ); + void scriptcallback_entity( quake3::SVarGroupList *& grouplist, eToken token ); + void scriptcallback_shader( quake3::SVarGroupList *& grouplist, eToken token ); + void scriptcallback_config( quake3::SVarGroupList *& grouplist, eToken token ); + + core::array < quake3::IShader > Shader; core::array < quake3::IShader > Entity; //quake3::tQ3EntityList Entity; - void scriptcallback_shader( quake3::SVarGroupList *& grouplist ); - core::array < quake3::IShader > Shader; + quake3::tStringList ShaderFile; void InitShader(); void ReleaseShader(); diff --git a/source/Irrlicht/CQuake3ShaderSceneNode.cpp b/source/Irrlicht/CQuake3ShaderSceneNode.cpp index 215e6ff4..ceed3836 100644 --- a/source/Irrlicht/CQuake3ShaderSceneNode.cpp +++ b/source/Irrlicht/CQuake3ShaderSceneNode.cpp @@ -23,6 +23,8 @@ namespace scene // who, if not you.. using namespace quake3; +/*! +*/ CQuake3ShaderSceneNode::CQuake3ShaderSceneNode( scene::ISceneNode* parent, scene::ISceneManager* mgr,s32 id, io::IFileSystem *fileSystem, scene::IMeshBuffer *original, @@ -55,8 +57,9 @@ CQuake3ShaderSceneNode::CQuake3ShaderSceneNode( Original->grab(); // clone meshbuffer to modifiable buffer - cloneBuffer( (scene::SMeshBufferLightMap*) original ); - + cloneBuffer( MeshBuffer, (scene::SMeshBufferLightMap*) original, + original->getMaterial().ColorMask != 0 + ); // load all Textures in all stages loadTextures( fileSystem ); @@ -65,7 +68,8 @@ CQuake3ShaderSceneNode::CQuake3ShaderSceneNode( } - +/*! +*/ CQuake3ShaderSceneNode::~CQuake3ShaderSceneNode() { if (Mesh) @@ -80,112 +84,48 @@ CQuake3ShaderSceneNode::~CQuake3ShaderSceneNode() /* create single copies */ -void CQuake3ShaderSceneNode::cloneBuffer( scene::SMeshBufferLightMap * buffer ) +void CQuake3ShaderSceneNode::cloneBuffer( scene::SMeshBuffer *dest, scene::SMeshBufferLightMap * buffer, bool translateCenter ) { - MeshBuffer->Material = buffer->Material; - MeshBuffer->Indices = buffer->Indices; - - video::S3DVertex dst; - core::aabbox3df bbox; + dest->Material = buffer->Material; + dest->Indices = buffer->Indices; const u32 vsize = buffer->Vertices.size(); - MeshBuffer->Vertices.reallocate( vsize ); + dest->Vertices.set_used( vsize ); for ( u32 i = 0; i!= vsize; ++i ) { const video::S3DVertex2TCoords& src = buffer->Vertices[i]; + video::S3DVertex &dst = dest->Vertices[i]; dst.Pos = src.Pos; dst.Normal = src.Normal; dst.Color = 0xFFFFFFFF; dst.TCoords = src.TCoords; - MeshBuffer->Vertices.push_back( dst ); if ( i == 0 ) - bbox.reset ( src.Pos ); + dest->BoundingBox.reset ( src.Pos ); else - bbox.addInternalPoint ( src.Pos ); + dest->BoundingBox.addInternalPoint ( src.Pos ); } // move the (temp) Mesh to a ScenePosititon // set Scene Node Position - setPosition( bbox.getCenter() ); - core::matrix4 m; - m.setTranslation( -bbox.getCenter() ); - SceneManager->getMeshManipulator()->transform( MeshBuffer, m ); - - // No Texture!. Use Shader-Pointer for sorting - MeshBuffer->Material.setTexture(0, (video::ITexture*) Shader); -} - -#if 0 -/* - create single copies -*/ -void CQuake3ShaderSceneNode::cloneBuffer( scene::SMeshBufferLightMap * buffer ) -{ - Original->Material = buffer->Material; - MeshBuffer->Material = buffer->Material; - - Original->Indices = buffer->Indices; - MeshBuffer->Indices = buffer->Indices; - - video::S3DVertex dst; - core::aabbox3df bbox; - - const u32 vsize = buffer->Vertices.size(); - - Original->Vertices.reallocate( vsize ); - MeshBuffer->Vertices.reallocate( vsize ); - for ( u32 i = 0; i!= vsize; ++i ) + if ( translateCenter ) { - const video::S3DVertex2TCoords& src = buffer->Vertices[i]; - - // Original has same Vertex Format - Original->Vertices.push_back(src); - - // we have a different vertex format -#if 0 - // automatic downcast to S3DVertex - MeshBuffer->Vertices.push_back(src); - MeshBuffer->Vertices.getLast().Color=0xFFFFFFFF; -#else - dst.Pos = src.Pos; - dst.Normal = src.Normal; - dst.Color = 0xFFFFFFFF; - dst.TCoords = src.TCoords; - MeshBuffer->Vertices.push_back( dst ); -#endif - - if ( i == 0 ) - bbox.reset ( src.Pos ); - else - bbox.addInternalPoint ( src.Pos ); - } - - //MeshBuffer->recalculateBoundingBox(); - - // move the (temp) Mesh to a ScenePosititon - // this is necessary for sorting transparent nodes - // this is necessary if you plane to attach child nodes - { - // original bounding box - //const core::aabbox3df& bbox = MeshBuffer->getBoundingBox(); - - // set Scene Node Position - setPosition( bbox.getCenter() ); + MeshOffset = dest->BoundingBox.getCenter(); + setPosition( MeshOffset ); core::matrix4 m; - m.setTranslation( -bbox.getCenter() ); - SceneManager->getMeshManipulator()->transform( Original, m ); - SceneManager->getMeshManipulator()->transform( MeshBuffer, m ); + m.setTranslation( -MeshOffset ); + SceneManager->getMeshManipulator()->transform( dest, m ); } + // No Texture!. Use Shader-Pointer for sorting - MeshBuffer->Material.setTexture(0, (video::ITexture*) Shader); + dest->Material.setTexture(0, (video::ITexture*) Shader); } -#endif + /* load the textures for all stages @@ -195,7 +135,7 @@ void CQuake3ShaderSceneNode::loadTextures( io::IFileSystem * fileSystem ) const SVarGroup *group; u32 i; - video::IVideoDriver *driver = SceneManager->getVideoDriver(); + video::IVideoDriver *driver = SceneManager->getVideoDriver(); // generic stage u32 mipmap = 0; @@ -308,13 +248,21 @@ E_SCENE_NODE_RENDER_PASS CQuake3ShaderSceneNode::getRenderStage() const } else */ - if ( strstr ( Shader->name.c_str(), "flame" ) - ) + if ( group->isDefined( "sort", "opaque" ) ) { - ret = ESNRP_TRANSPARENT_EFFECT; + ret = ESNRP_SOLID; } else - if ( group->isDefined( "surfaceparm", "water" ) ) + if ( group->isDefined( "sort", "additive" ) ) + { + ret = ESNRP_TRANSPARENT; + } + else + if ( strstr ( Shader->name.c_str(), "flame" ) || + group->isDefined( "surfaceparm", "water" ) || + group->isDefined( "sort", "underwater" ) || + group->isDefined( "sort", "underwater" ) + ) { ret = ESNRP_TRANSPARENT_EFFECT; } @@ -360,10 +308,6 @@ void CQuake3ShaderSceneNode::render() material.setTexture(1, 0); material.NormalizeNormals = false; -/* - if ( 0 == strstr ( Shader->name.c_str(), "chapthroatooz" ) ) - return; -*/ // generic stage group = Shader->getGroup( 1 ); material.BackfaceCulling = getCullingFunction( group->get( "cull" ) ); @@ -371,10 +315,6 @@ void CQuake3ShaderSceneNode::render() u32 pushProjection = 0; core::matrix4 projection ( core::matrix4::EM4CONST_NOTHING ); -/* - if ( !group->isDefined ( "deformvertexes", "autosprite2" ) ) - return; -*/ // decal ( solve z-fighting ) if ( group->isDefined( "polygonoffset" ) ) { @@ -400,7 +340,6 @@ void CQuake3ShaderSceneNode::render() driver->setTransform(video::ETS_WORLD, AbsoluteTransformation ); //! render all stages - //u32 drawCount = group->isDefined( "surfaceparm", "trans" ); u32 drawCount = (pass == ESNRP_TRANSPARENT_EFFECT) ? 1 : 0; core::matrix4 textureMatrix ( core::matrix4::EM4CONST_NOTHING ); for ( u32 stage = 1; stage < Shader->VarGroup->VariableGroup.size(); ++stage ) @@ -564,16 +503,14 @@ void CQuake3ShaderSceneNode::deformvertexes_wave( f32 dt, SModifierFunction &fun const f32 phase = function.phase; - const u32 vsize = MeshBuffer->Vertices.size(); + const u32 vsize = Original->Vertices.size(); for ( u32 i = 0; i != vsize; ++i ) { const video::S3DVertex2TCoords &src = Original->Vertices[i]; video::S3DVertex &dst = MeshBuffer->Vertices[i]; if ( 0 == function.count ) - { - dst.Pos = src.Pos - getPosition (); - } + dst.Pos = src.Pos - MeshOffset; const f32 wavephase = (dst.Pos.X + dst.Pos.Y + dst.Pos.Z) * function.wave; function.phase = phase + wavephase; @@ -613,22 +550,19 @@ void CQuake3ShaderSceneNode::deformvertexes_wave( f32 dt, SModifierFunction &fun If an object is made up of surfaces with different shaders, all must have matching deformVertexes move values or the object will appear to tear itself apart. */ - void CQuake3ShaderSceneNode::deformvertexes_move( f32 dt, SModifierFunction &function ) { function.wave = core::reciprocal( function.wave ); const f32 f = function.evaluate( dt ); - const u32 vsize = MeshBuffer->Vertices.size(); + const u32 vsize = Original->Vertices.size(); for ( u32 i = 0; i != vsize; ++i ) { const video::S3DVertex2TCoords &src = Original->Vertices[i]; video::S3DVertex &dst = MeshBuffer->Vertices[i]; if ( 0 == function.count ) - { - dst.Pos = src.Pos - getPosition (); - } + dst.Pos = src.Pos - MeshOffset; dst.Pos.X += f * function.x; dst.Pos.Y += f * function.y; @@ -657,7 +591,7 @@ void CQuake3ShaderSceneNode::deformvertexes_move( f32 dt, SModifierFunction &fun void CQuake3ShaderSceneNode::deformvertexes_normal( f32 dt, SModifierFunction &function ) { function.func = SINUS; - const u32 vsize = MeshBuffer->Vertices.size(); + const u32 vsize = Original->Vertices.size(); for ( u32 i = 0; i != vsize; ++i ) { const video::S3DVertex2TCoords &src = Original->Vertices[i]; @@ -733,7 +667,7 @@ void CQuake3ShaderSceneNode::deformvertexes_bulge( f32 dt, SModifierFunction &fu dt *= function.bulgespeed * 0.1f; const f32 phase = function.phase; - const u32 vsize = MeshBuffer->Vertices.size(); + const u32 vsize = Original->Vertices.size(); for ( u32 i = 0; i != vsize; ++i ) { const video::S3DVertex2TCoords &src = Original->Vertices[i]; @@ -745,9 +679,7 @@ void CQuake3ShaderSceneNode::deformvertexes_bulge( f32 dt, SModifierFunction &fu const f32 f = function.evaluate( dt ); if ( 0 == function.count ) - { - dst.Pos = src.Pos - getPosition (); - } + dst.Pos = src.Pos - MeshOffset; dst.Pos.X += f * src.Normal.X; dst.Pos.Y += f * src.Normal.Y; @@ -777,7 +709,7 @@ void CQuake3ShaderSceneNode::deformvertexes_bulge( f32 dt, SModifierFunction &fu */ void CQuake3ShaderSceneNode::deformvertexes_autosprite( f32 dt, SModifierFunction &function ) { - u32 vsize = MeshBuffer->Vertices.size(); + u32 vsize = Original->Vertices.size(); u32 g; u32 i; @@ -795,7 +727,7 @@ void CQuake3ShaderSceneNode::deformvertexes_autosprite( f32 dt, SModifierFunctio core::vector3df forward = camPos - center; q.rotationFromTo ( vin[i].Normal, forward ); - q.getMatrixCenter ( lookat, center, getPosition () ); + q.getMatrixCenter ( lookat, center, MeshOffset ); for ( g = 0; g < 4; ++g ) { @@ -823,10 +755,11 @@ struct sortaxis return v.getLengthSQ () < other.v.getLengthSQ (); } }; - +/*! +*/ void CQuake3ShaderSceneNode::deformvertexes_autosprite2( f32 dt, SModifierFunction &function ) { - u32 vsize = MeshBuffer->Vertices.size(); + u32 vsize = Original->Vertices.size(); u32 g; u32 i; @@ -852,7 +785,7 @@ void CQuake3ShaderSceneNode::deformvertexes_autosprite2( f32 dt, SModifierFuncti axis.set_sorted ( false ); axis.sort (); - lookat.buildAxisAlignedBillboard ( camPos, center, getPosition (), axis[1].v, vin[i+0].Normal ); + lookat.buildAxisAlignedBillboard ( camPos, center, MeshOffset, axis[1].v, vin[i+0].Normal ); for ( g = 0; g < 4; ++g ) { @@ -869,7 +802,7 @@ void CQuake3ShaderSceneNode::deformvertexes_autosprite2( f32 dt, SModifierFuncti void CQuake3ShaderSceneNode::vertextransform_rgbgen( f32 dt, SModifierFunction &function ) { u32 i; - const u32 vsize = MeshBuffer->Vertices.size(); + const u32 vsize = Original->Vertices.size(); switch ( function.rgbgen ) { @@ -921,7 +854,7 @@ void CQuake3ShaderSceneNode::vertextransform_rgbgen( f32 dt, SModifierFunction & void CQuake3ShaderSceneNode::vertextransform_alphagen( f32 dt, SModifierFunction &function ) { u32 i; - const u32 vsize = MeshBuffer->Vertices.size(); + const u32 vsize = Original->Vertices.size(); switch ( function.alphagen ) { @@ -950,7 +883,7 @@ void CQuake3ShaderSceneNode::vertextransform_alphagen( f32 dt, SModifierFunction { // alphagen lightingspecular TODO!!! const SViewFrustum *frustum = SceneManager->getActiveCamera()->getViewFrustum(); - const core::matrix4 &view = frustum->Matrices [ video::ETS_VIEW ]; + const core::matrix4 &view = frustum->getTransform ( video::ETS_VIEW ); const f32 *m = view.pointer(); @@ -985,7 +918,7 @@ void CQuake3ShaderSceneNode::vertextransform_alphagen( f32 dt, SModifierFunction void CQuake3ShaderSceneNode::vertextransform_tcgen( f32 dt, SModifierFunction &function ) { u32 i; - const u32 vsize = MeshBuffer->Vertices.size(); + const u32 vsize = Original->Vertices.size(); switch ( function.tcgen ) { @@ -1026,7 +959,7 @@ void CQuake3ShaderSceneNode::vertextransform_tcgen( f32 dt, SModifierFunction &f { // tcgen environment const SViewFrustum *frustum = SceneManager->getActiveCamera()->getViewFrustum(); - const core::matrix4 &view = frustum->Matrices [ video::ETS_VIEW ]; + const core::matrix4 &view = frustum->getTransform ( video::ETS_VIEW ); const f32 *m = view.pointer(); @@ -1044,35 +977,6 @@ void CQuake3ShaderSceneNode::vertextransform_tcgen( f32 dt, SModifierFunction &f MeshBuffer->Vertices[i].TCoords.Y = 0.5f*(1.f+(n.X*m[4]+n.Y*m[5]+n.Z*m[6])); } -#if 0 - // tcgen environment - // using eye linear, sphere map may be cooler;-) - // modelmatrix is identity - const SViewFrustum *frustum = SceneManager->getActiveCamera()->getViewFrustum(); - const core::matrix4 &view = frustum->Matrices [ video::ETS_VIEW ]; - const core::matrix4 &viewinverse = frustum->Matrices [ SViewFrustum::ETS_VIEW_MODEL_INVERSE_3 ]; - - // eyePlane - core::vector3df eyePlaneS; - core::vector3df eyePlaneT; - - viewinverse.rotateVect( eyePlaneS, core::vector3df(1.f, 0.f, 0.f) ); - viewinverse.rotateVect( eyePlaneT, core::vector3df(0.f, 1.f, 0.f) ); - - eyePlaneS.normalize(); - eyePlaneT.normalize(); - - core::vector3df v; - for ( i = 0; i != vsize; ++i ) - { - // vertex in eye space - view.rotateVect( v, Original->Vertices[i].Pos ); - v.normalize(); - - MeshBuffer->Vertices[i].TCoords.X = ( (1.f + eyePlaneS.dotProduct(v) ) * 0.5f ); - MeshBuffer->Vertices[i].TCoords.Y = ( (1.f - eyePlaneT.dotProduct(v) ) * 0.5f ); - } -#endif } break; default: break; diff --git a/source/Irrlicht/CQuake3ShaderSceneNode.h b/source/Irrlicht/CQuake3ShaderSceneNode.h index 06f527ef..fde277a7 100644 --- a/source/Irrlicht/CQuake3ShaderSceneNode.h +++ b/source/Irrlicht/CQuake3ShaderSceneNode.h @@ -52,6 +52,7 @@ private: SMesh *Mesh; SMeshBufferLightMap* Original; SMeshBuffer* MeshBuffer; + core::vector3df MeshOffset; struct SQ3Texture { @@ -74,7 +75,7 @@ private: void loadTextures ( io::IFileSystem * fileSystem ); void addBuffer ( scene::SMeshBufferLightMap * buffer ); - void cloneBuffer ( scene::SMeshBufferLightMap * buffer ); + void cloneBuffer ( scene::SMeshBuffer *dest, scene::SMeshBufferLightMap * buffer, bool translateCenter ); void deformvertexes_wave ( f32 dt, quake3::SModifierFunction &function ); void deformvertexes_move ( f32 dt, quake3::SModifierFunction &function ); diff --git a/source/Irrlicht/CSceneManager.cpp b/source/Irrlicht/CSceneManager.cpp index 7cc94a1e..4b37aff8 100644 --- a/source/Irrlicht/CSceneManager.cpp +++ b/source/Irrlicht/CSceneManager.cpp @@ -239,7 +239,7 @@ CSceneManager::CSceneManager(video::IVideoDriver* driver, io::IFileSystem* fs, MeshLoaderList.push_back(new COBJMeshFileLoader(this, FileSystem)); #endif #ifdef _IRR_COMPILE_WITH_MD3_LOADER_ - MeshLoaderList.push_back(new CMD3MeshFileLoader()); + MeshLoaderList.push_back(new CMD3MeshFileLoader( this)); #endif #ifdef _IRR_COMPILE_WITH_B3D_LOADER_ MeshLoaderList.push_back(new CB3DMeshFileLoader(this)); @@ -412,6 +412,15 @@ gui::IGUIEnvironment* CSceneManager::getGUIEnvironment() return GUIEnvironment; } +//! Get the active FileSystem +/** \return Pointer to the FileSystem +This pointer should not be dropped. See IReferenceCounted::drop() for more information. */ +io::IFileSystem* CSceneManager::getFileSystem() +{ + return FileSystem; +} + + //! Adds a text scene node, which is able to display //! 2d text at a position in three dimensional space @@ -1097,8 +1106,8 @@ bool CSceneManager::isCulled(const ISceneNode* node) SViewFrustum frust = *cam->getViewFrustum(); //transform the frustum to the node's current absolute transformation - core::matrix4 invTrans(node->getAbsoluteTransformation()); - invTrans.makeInverse(); + core::matrix4 invTrans(node->getAbsoluteTransformation(), core::matrix4::EM4CONST_INVERSE); + //invTrans.makeInverse(); frust.transform(invTrans); core::vector3df edges[8]; @@ -1560,14 +1569,15 @@ ISceneNodeAnimator* CSceneManager::createRotationAnimator(const core::vector3df& ISceneNodeAnimator* CSceneManager::createFlyCircleAnimator( const core::vector3df& center, f32 radius, f32 speed, const core::vector3df& direction, - f32 startPosition) + f32 startPosition, + f32 radiusEllipsoid) { const f32 orbitDurationMs = (core::DEGTORAD * 360.f) / speed; const u32 effectiveTime = os::Timer::getTime() + (u32)(orbitDurationMs * startPosition); ISceneNodeAnimator* anim = new CSceneNodeAnimatorFlyCircle( effectiveTime, center, - radius, speed, direction); + radius, speed, direction,radiusEllipsoid); return anim; } @@ -1575,10 +1585,10 @@ ISceneNodeAnimator* CSceneManager::createFlyCircleAnimator( //! Creates a fly straight animator, which lets the attached scene node //! fly or move along a line between two points. ISceneNodeAnimator* CSceneManager::createFlyStraightAnimator(const core::vector3df& startPoint, - const core::vector3df& endPoint, u32 timeForWay, bool loop) + const core::vector3df& endPoint, u32 timeForWay, bool loop,bool pingpong) { ISceneNodeAnimator* anim = new CSceneNodeAnimatorFlyStraight(startPoint, - endPoint, timeForWay, loop, os::Timer::getTime()); + endPoint, timeForWay, loop, os::Timer::getTime(), pingpong); return anim; } @@ -2409,7 +2419,7 @@ ISceneNode* CSceneManager::addSceneNode(const char* sceneNodeTypeName, ISceneNod //! Returns a typename from a scene node animator type or null if not found -const c8* CSceneManager::getAnimatorTypeName(ESCENE_NODE_ANIMATOR_TYPE type) const +const c8* CSceneManager::getAnimatorTypeName(ESCENE_NODE_ANIMATOR_TYPE type) { const char* name = 0; diff --git a/source/Irrlicht/CSceneManager.h b/source/Irrlicht/CSceneManager.h index 13b110c0..22776da1 100644 --- a/source/Irrlicht/CSceneManager.h +++ b/source/Irrlicht/CSceneManager.h @@ -52,8 +52,13 @@ namespace scene //! returns the video driver virtual video::IVideoDriver* getVideoDriver(); + //! return the gui environment virtual gui::IGUIEnvironment* getGUIEnvironment(); + //! return the filesystem + virtual io::IFileSystem* CSceneManager::getFileSystem(); + + //! adds Volume Lighting Scene Node. //! the returned pointer must not be dropped. virtual IVolumeLightSceneNode* addVolumeLightSceneNode(ISceneNode* parent=0, s32 id=-1, @@ -292,12 +297,13 @@ namespace scene const core::vector3df& center=core::vector3df(0.f, 0.f, 0.f), f32 radius=100.f, f32 speed=0.001f, const core::vector3df& direction=core::vector3df(0.f, 1.f, 0.f), - f32 startPosition = 0.f); + f32 startPosition = 0.f, + f32 radiusEllipsoid = 0.f); //! Creates a fly straight animator, which lets the attached scene node //! fly or move along a line between two points. virtual ISceneNodeAnimator* createFlyStraightAnimator(const core::vector3df& startPoint, - const core::vector3df& endPoint, u32 timeForWay, bool loop=false); + const core::vector3df& endPoint, u32 timeForWay, bool loop=false,bool pingpong = false); //! Creates a texture animator, which switches the textures of the target scene //! node based on a list of textures. @@ -420,6 +426,9 @@ namespace scene //! Returns a typename from a scene node type or null if not found virtual const c8* getSceneNodeTypeName(ESCENE_NODE_TYPE type); + //! Returns a typename from a scene node animator type or null if not found + virtual const c8* getAnimatorTypeName(ESCENE_NODE_ANIMATOR_TYPE type); + //! Adds a scene node to the scene by name virtual ISceneNode* addSceneNode(const char* sceneNodeTypeName, ISceneNode* parent=0); @@ -469,9 +478,6 @@ namespace scene private: - //! Returns a typename from a scene node animator type or null if not found - virtual const c8* getAnimatorTypeName(ESCENE_NODE_ANIMATOR_TYPE type) const; - //! returns if node is culled bool isCulled(const ISceneNode* node); diff --git a/source/Irrlicht/CSceneNodeAnimatorFlyCircle.cpp b/source/Irrlicht/CSceneNodeAnimatorFlyCircle.cpp index 8c7d397d..8daf534e 100644 --- a/source/Irrlicht/CSceneNodeAnimatorFlyCircle.cpp +++ b/source/Irrlicht/CSceneNodeAnimatorFlyCircle.cpp @@ -10,8 +10,10 @@ namespace scene { //! constructor -CSceneNodeAnimatorFlyCircle::CSceneNodeAnimatorFlyCircle(u32 time, const core::vector3df& center, f32 radius, f32 speed, const core::vector3df& direction) -: Center(center), Direction(direction), Radius(radius), Speed(speed), StartTime(time) +CSceneNodeAnimatorFlyCircle::CSceneNodeAnimatorFlyCircle(u32 time, const core::vector3df& center, f32 radius, + f32 speed, const core::vector3df& direction, + f32 radiusEllipsoid) +: Center(center), Direction(direction), Radius(radius), RadiusEllipsoid (radiusEllipsoid), Speed(speed), StartTime(time) { #ifdef _DEBUG setDebugName("CSceneNodeAnimatorFlyCircle"); @@ -46,7 +48,9 @@ void CSceneNodeAnimatorFlyCircle::animateNode(ISceneNode* node, u32 timeMs) else time = (timeMs-StartTime) * Speed; - node->setPosition(Center + Radius * ((VecU*cosf(time)) + (VecV*sinf(time)))); +// node->setPosition(Center + Radius * ((VecU*cosf(time)) + (VecV*sinf(time)))); + f32 r2 = RadiusEllipsoid == 0.f ? Radius : RadiusEllipsoid; + node->setPosition(Center + (Radius*cosf(time)*VecU) + (r2*sinf(time)*VecV ) ); } @@ -57,6 +61,7 @@ void CSceneNodeAnimatorFlyCircle::serializeAttributes(io::IAttributes* out, io:: out->addFloat("Radius", Radius); out->addFloat("Speed", Speed); out->addVector3d("Direction", Direction); + out->addFloat("RadiusEllipsoid", Radius); } @@ -73,13 +78,15 @@ void CSceneNodeAnimatorFlyCircle::deserializeAttributes(io::IAttributes* in, io: Direction.set(0,1,0); // irrlicht 1.1 backwards compatibility else Direction.normalize(); + + RadiusEllipsoid = in->getAttributeAsFloat("RadiusEllipsoid"); init(); } ISceneNodeAnimator* CSceneNodeAnimatorFlyCircle::createClone(ISceneNode* node, ISceneManager* newManager) { CSceneNodeAnimatorFlyCircle * newAnimator = - new CSceneNodeAnimatorFlyCircle(StartTime, Center, Radius, Speed, Direction); + new CSceneNodeAnimatorFlyCircle(StartTime, Center, Radius, Speed, Direction, RadiusEllipsoid); return newAnimator; } diff --git a/source/Irrlicht/CSceneNodeAnimatorFlyCircle.h b/source/Irrlicht/CSceneNodeAnimatorFlyCircle.h index 675c7992..3b6826da 100644 --- a/source/Irrlicht/CSceneNodeAnimatorFlyCircle.h +++ b/source/Irrlicht/CSceneNodeAnimatorFlyCircle.h @@ -18,7 +18,8 @@ namespace scene //! constructor CSceneNodeAnimatorFlyCircle(u32 time, const core::vector3df& center, f32 radius, - f32 speed, const core::vector3df& direction); + f32 speed, const core::vector3df& direction, + f32 radiusEllipsoid); //! animates a scene node virtual void animateNode(ISceneNode* node, u32 timeMs); @@ -50,6 +51,7 @@ namespace scene core::vector3df VecU; core::vector3df VecV; f32 Radius; + f32 RadiusEllipsoid; f32 Speed; u32 StartTime; }; diff --git a/source/Irrlicht/CSceneNodeAnimatorFlyStraight.cpp b/source/Irrlicht/CSceneNodeAnimatorFlyStraight.cpp index 0eafb03e..d2d792ff 100644 --- a/source/Irrlicht/CSceneNodeAnimatorFlyStraight.cpp +++ b/source/Irrlicht/CSceneNodeAnimatorFlyStraight.cpp @@ -13,10 +13,10 @@ namespace scene //! constructor CSceneNodeAnimatorFlyStraight::CSceneNodeAnimatorFlyStraight(const core::vector3df& startPoint, const core::vector3df& endPoint, u32 timeForWay, - bool loop, u32 now) + bool loop, u32 now, bool pingpong) : ISceneNodeAnimatorFinishing(now + timeForWay), Start(startPoint), End(endPoint), WayLength(0.0f), - TimeFactor(0.0f), StartTime(now), TimeForWay(timeForWay), Loop(loop) + TimeFactor(0.0f), StartTime(now), TimeForWay(timeForWay), Loop(loop), PingPong ( pingpong ) { #ifdef _DEBUG setDebugName("CSceneNodeAnimatorFlyStraight"); @@ -61,7 +61,17 @@ void CSceneNodeAnimatorFlyStraight::animateNode(ISceneNode* node, u32 timeMs) } else { - pos += Vector * (f32)fmod((f32)t, (f32)TimeForWay) * TimeFactor; + f32 phase = fmodf( (f32) t, (f32) TimeForWay ); + core::vector3df rel = Vector * phase * TimeFactor; + + if ( !PingPong || phase < TimeForWay * 0.5f ) + { + pos += rel; + } + else + { + pos = End - rel; + } } node->setPosition(pos); @@ -75,6 +85,7 @@ void CSceneNodeAnimatorFlyStraight::serializeAttributes(io::IAttributes* out, io out->addVector3d("End", End); out->addInt("TimeForWay", TimeForWay); out->addBool("Loop", Loop); + out->addBool("PingPong", PingPong); } @@ -85,6 +96,7 @@ void CSceneNodeAnimatorFlyStraight::deserializeAttributes(io::IAttributes* in, i End = in->getAttributeAsVector3d("End"); TimeForWay = in->getAttributeAsInt("TimeForWay"); Loop = in->getAttributeAsBool("Loop"); + PingPong = in->getAttributeAsBool("PingPong"); recalculateIntermediateValues(); } @@ -92,7 +104,7 @@ void CSceneNodeAnimatorFlyStraight::deserializeAttributes(io::IAttributes* in, i ISceneNodeAnimator* CSceneNodeAnimatorFlyStraight::createClone(ISceneNode* node, ISceneManager* newManager) { CSceneNodeAnimatorFlyStraight * newAnimator = - new CSceneNodeAnimatorFlyStraight(Start, End, TimeForWay, Loop, StartTime); + new CSceneNodeAnimatorFlyStraight(Start, End, TimeForWay, Loop, StartTime, PingPong); return newAnimator; } diff --git a/source/Irrlicht/CSceneNodeAnimatorFlyStraight.h b/source/Irrlicht/CSceneNodeAnimatorFlyStraight.h index b6342bc9..ea1d2eb6 100644 --- a/source/Irrlicht/CSceneNodeAnimatorFlyStraight.h +++ b/source/Irrlicht/CSceneNodeAnimatorFlyStraight.h @@ -19,7 +19,7 @@ namespace scene CSceneNodeAnimatorFlyStraight(const core::vector3df& startPoint, const core::vector3df& endPoint, u32 timeForWay, - bool loop, u32 now); + bool loop, u32 now, bool pingpong); //! destructor virtual ~CSceneNodeAnimatorFlyStraight(); @@ -54,6 +54,7 @@ namespace scene u32 StartTime; u32 TimeForWay; bool Loop; + bool PingPong; }; diff --git a/source/Irrlicht/CSoftwareDriver2.cpp b/source/Irrlicht/CSoftwareDriver2.cpp index dce59359..f6d7c04c 100644 --- a/source/Irrlicht/CSoftwareDriver2.cpp +++ b/source/Irrlicht/CSoftwareDriver2.cpp @@ -113,13 +113,12 @@ CBurningVideoDriver::CBurningVideoDriver(const core::dimension2d& windowSiz umr->drop (); // select render target - setRenderTarget(BackBuffer); - LightSpace.Global_AmbientLight.set ( 0.f, 0.f, 0.f, 0.f ); + //reset Lightspace + LightSpace.reset (); // select the right renderer - //CurrentShader = BurningShader[ETR_REFERENCE]; setCurrentShader(); } @@ -150,42 +149,37 @@ CBurningVideoDriver::~CBurningVideoDriver() } -//! void selects the right triangle renderer based on the render states. +/*! + selects the right triangle renderer based on the render states. +*/ void CBurningVideoDriver::setCurrentShader() { - EBurningFFShader shader = ETR_TEXTURE_GOURAUD; + ITexture *texture0 = Material.org.getTexture(0); + ITexture *texture1 = Material.org.getTexture(1); + + bool zMaterialTest = Material.org.ZBuffer != ECFN_NEVER && + Material.org.ZWriteEnable && + ( AllowZWriteOnTransparent || !Material.org.isTransparent() ); + + EBurningFFShader shader = zMaterialTest ? ETR_TEXTURE_GOURAUD : ETR_TEXTURE_GOURAUD_NOZ; - bool zMaterialTest = true; switch ( Material.org.MaterialType ) { case EMT_ONETEXTURE_BLEND: shader = ETR_TEXTURE_BLEND; - zMaterialTest = false; break; case EMT_TRANSPARENT_ALPHA_CHANNEL_REF: case EMT_TRANSPARENT_ALPHA_CHANNEL: - if ( Material.org.ZBuffer != ECFN_NEVER ) + if ( texture0 && texture0->hasAlpha () ) { - shader = ETR_TEXTURE_GOURAUD_ALPHA; + shader = zMaterialTest ? ETR_TEXTURE_GOURAUD_ALPHA : ETR_TEXTURE_GOURAUD_ALPHA_NOZ; + break; } - else - { - shader = ETR_TEXTURE_GOURAUD_ALPHA_NOZ; - } - zMaterialTest = false; - break; + // fall through case EMT_TRANSPARENT_ADD_COLOR: - if ( Material.org.ZBuffer != ECFN_NEVER ) - { - shader = ETR_TEXTURE_GOURAUD_ADD; - } - else - { - shader = ETR_TEXTURE_GOURAUD_ADD_NO_Z; - } - zMaterialTest = false; + shader = zMaterialTest ? ETR_TEXTURE_GOURAUD_ADD : ETR_TEXTURE_GOURAUD_ADD_NO_Z; break; case EMT_TRANSPARENT_VERTEX_ALPHA: @@ -203,16 +197,16 @@ void CBurningVideoDriver::setCurrentShader() break; case EMT_LIGHTMAP_LIGHTING_M4: - if ( Material.org.getTexture(1) ) + if ( texture1 ) shader = ETR_TEXTURE_GOURAUD_LIGHTMAP_M4; break; case EMT_LIGHTMAP_M4: - if ( Material.org.getTexture(1) ) + if ( texture1 ) shader = ETR_TEXTURE_LIGHTMAP_M4; break; case EMT_LIGHTMAP_ADD: - if ( Material.org.getTexture(1) ) + if ( texture1 ) shader = ETR_TEXTURE_GOURAUD_LIGHTMAP_ADD; break; @@ -229,12 +223,7 @@ void CBurningVideoDriver::setCurrentShader() } - if ( zMaterialTest && (Material.org.ZBuffer==ECFN_NEVER) && !Material.org.ZWriteEnable) - { - shader = ETR_TEXTURE_GOURAUD_NOZ; - } - - if ( 0 == Material.org.getTexture(0) ) + if ( !texture0 ) { shader = ETR_GOURAUD; } @@ -266,11 +255,6 @@ void CBurningVideoDriver::setCurrentShader() } } - if ( shader != ETR_TEXTURE_BLEND ) - { - //CurrentShader = 0; - } - } @@ -317,6 +301,7 @@ void CBurningVideoDriver::setTransform(E_TRANSFORMATION_STATE state, const core: Transformation[ETS_PROJECTION], Transformation[ETS_VIEW] ); + TransformationFlag [ ETS_VIEW_INVERSE ] = 0; break; case ETS_WORLD: @@ -332,26 +317,6 @@ void CBurningVideoDriver::setTransform(E_TRANSFORMATION_STATE state, const core: ); } TransformationFlag[ETS_CURRENT] = 0; - -#ifdef SOFTWARE_DRIVER_2_LIGHTING - if ( Material.org.Lighting ) - { - if ( TransformationFlag[state] ) - { - Transformation[ETS_WORLD_VIEW] = Transformation[ETS_VIEW]; - } - else - { - Transformation[ETS_WORLD_VIEW].setbyproduct_nocheck ( - Transformation[ETS_VIEW], - Transformation[ETS_WORLD] - ); - } - core::matrix4 m2 ( Transformation[ETS_WORLD_VIEW] ); - m2.makeInverse (); - m2.getTransposed ( Transformation[ETS_WORLD_VIEW_INVERSE_TRANSPOSED] ); - } -#endif break; default: break; @@ -359,31 +324,6 @@ void CBurningVideoDriver::setTransform(E_TRANSFORMATION_STATE state, const core: } -//! sets a material -void CBurningVideoDriver::setMaterial(const SMaterial& material) -{ - Material.org = material; - OverrideMaterial.apply(Material.org); - - Material.AmbientColor.setA8R8G8B8 ( Material.org.AmbientColor.color ); - Material.DiffuseColor.setA8R8G8B8 ( Material.org.DiffuseColor.color ); - Material.EmissiveColor.setA8R8G8B8 ( Material.org.EmissiveColor.color ); - Material.SpecularColor.setA8R8G8B8 ( Material.org.SpecularColor.color ); - - Material.SpecularEnabled = Material.org.Shininess != 0.f; - if (Material.SpecularEnabled) - Material.org.NormalizeNormals = true; - - for (u32 i = 0; i < 2; ++i) - { - setTransform((E_TRANSFORMATION_STATE) (ETS_TEXTURE_0 + i), - material.getTextureMatrix(i)); - } - - setCurrentShader(); -} - - //! clears the zbuffer bool CBurningVideoDriver::beginScene(bool backBuffer, bool zBuffer, SColor color, void* windowId, core::rect* sourceRect) @@ -891,7 +831,6 @@ void CBurningVideoDriver::VertexCache_fill(const u32 sourceIndex, Transformation [ ETS_CURRENT].transformVect ( &dest->Pos.x, ((S3DVertex*) source )->Pos ); #ifdef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR - // light Vertex #ifdef SOFTWARE_DRIVER_2_LIGHTING lightVertex ( dest, ((S3DVertex*) source ) ); @@ -1374,13 +1313,6 @@ s32 CBurningVideoDriver::addDynamicLight(const SLight& dl) l.org = dl; l.LightIsOn = true; - // light in eye space - Transformation[ETS_VIEW].transformVect ( &l.posEyeSpace.x, l.org.Position ); - - l.constantAttenuation = l.org.Attenuation.X; - l.linearAttenuation = l.org.Attenuation.Y; - l.quadraticAttenuation = l.org.Attenuation.Z; - l.AmbientColor.setColorf ( l.org.AmbientColor ); l.DiffuseColor.setColorf ( l.org.DiffuseColor ); l.SpecularColor.setColorf ( l.org.SpecularColor ); @@ -1388,9 +1320,22 @@ s32 CBurningVideoDriver::addDynamicLight(const SLight& dl) switch ( dl.Type ) { case video::ELT_DIRECTIONAL: - { - l.posEyeSpace.normalize_xyz (); - } break; + l.posLightSpace.x = -l.org.Direction.X; + l.posLightSpace.y = -l.org.Direction.Y; + l.posLightSpace.z = -l.org.Direction.Z; + l.posLightSpace.w = 1.f; + break; + case ELT_POINT: + case ELT_SPOT: + LightSpace.Flags |= POINTLIGHT; + l.posLightSpace.x = l.org.Position.X; + l.posLightSpace.y = l.org.Position.Y; + l.posLightSpace.z = l.org.Position.Z; + l.posLightSpace.w = 1.f; + l.constantAttenuation = l.org.Attenuation.X; + l.linearAttenuation = l.org.Attenuation.Y; + l.quadraticAttenuation = l.org.Attenuation.Z; + break; } LightSpace.Light.push_back ( l ); @@ -1408,7 +1353,7 @@ void CBurningVideoDriver::turnLightOn(s32 lightIndex, bool turnOn) //! deletes all dynamic lights there are void CBurningVideoDriver::deleteAllDynamicLights() { - LightSpace.Light.set_used ( 0 ); + LightSpace.reset (); CNullDriver::deleteAllDynamicLights(); } @@ -1420,15 +1365,52 @@ u32 CBurningVideoDriver::getMaximalDynamicLightAmount() const } +//! sets a material +void CBurningVideoDriver::setMaterial(const SMaterial& material) +{ + Material.org = material; + +#ifdef SOFTWARE_DRIVER_2_TEXTURE_TRANSFORM + for (u32 i = 0; i < 2; ++i) + { + setTransform((E_TRANSFORMATION_STATE) (ETS_TEXTURE_0 + i), + material.getTextureMatrix(i)); + } +#endif #ifdef SOFTWARE_DRIVER_2_LIGHTING + Material.AmbientColor.setA8R8G8B8 ( Material.org.AmbientColor.color ); + Material.DiffuseColor.setA8R8G8B8 ( Material.org.DiffuseColor.color ); + Material.EmissiveColor.setA8R8G8B8 ( Material.org.EmissiveColor.color ); + Material.SpecularColor.setA8R8G8B8 ( Material.org.SpecularColor.color ); + + core::setbit_cond ( LightSpace.Flags, Material.org.Shininess != 0.f, SPECULAR ); + core::setbit_cond ( LightSpace.Flags, Material.org.FogEnable, FOG ); + core::setbit_cond ( LightSpace.Flags, Material.org.NormalizeNormals, NORMALIZE ); +#endif + + setCurrentShader(); +} + + + +#ifdef SOFTWARE_DRIVER_2_LIGHTING + +//! Sets the fog mode. +void CBurningVideoDriver::setFog(SColor color, bool linearFog, f32 start, + f32 end, f32 density, bool pixelFog, bool rangeFog) +{ + CNullDriver::setFog(color, linearFog, start, end, density, pixelFog, rangeFog); + LightSpace.FogColor.setA8R8G8B8 ( color.color ); +} + /*! */ void CBurningVideoDriver::lightVertex ( s4DVertex *dest, const S3DVertex *source ) { // apply lighting model - if ( false == Material.org.Lighting ) + if ( !Material.org.Lighting ) { // should use the DiffuseColor but using pre-lit vertex color dest->Color[0].setA8R8G8B8 ( source->Color.color ); @@ -1437,44 +1419,51 @@ void CBurningVideoDriver::lightVertex ( s4DVertex *dest, const S3DVertex *source sVec4 dColor; + dColor = LightSpace.Global_AmbientLight; + dColor += Material.EmissiveColor; + if ( Lights.size () == 0 ) { - dColor = LightSpace.Global_AmbientLight; - dColor += Material.EmissiveColor; dColor.saturate(); - dest->Color[0] = dColor; return; } - // eyespace -/* - core::matrix4 modelview = Transformation[ETS_WORLD].m * Transformation[ETS_VIEW].m; + sVec4 vertexLightSpace; + sVec4 normalLightSpace; + sVec4 eyeLightSpace; - core::matrix4 m2 ( modelview ); - m2.makeInverse (); - core::matrix4 modelviewinversetransposed ( m2.getTransposed() ); -*/ + // vertex normal in light space + Transformation[ETS_WORLD].rotateVect ( &normalLightSpace.x, source->Normal ); + if ( LightSpace.Flags & NORMALIZE ) + normalLightSpace.normalize_xyz(); - sVec4 vertexEyeSpace; - sVec4 normalEyeSpace; - sVec4 vertexEyeSpaceUnit; + // vertex in light space + if ( LightSpace.Flags & ( POINTLIGHT | FOG | SPECULAR ) ) + Transformation[ETS_WORLD].transformVect ( &vertexLightSpace.x, source->Pos ); - // vertex in eye space - Transformation[ETS_WORLD_VIEW].transformVect ( &vertexEyeSpace.x, source->Pos ); - vertexEyeSpace.project_xyz (); - - vertexEyeSpaceUnit = vertexEyeSpace; - vertexEyeSpaceUnit.normalize_xyz(); - - // vertex normal in eye-space - //modelviewinversetransposed.transformVect ( &normalEyeSpace.x, source->Normal ); - Transformation[ETS_WORLD_VIEW_INVERSE_TRANSPOSED].rotateVect ( &normalEyeSpace.x, source->Normal ); - if ( Material.org.NormalizeNormals ) + // eye in in light space + if ( LightSpace.Flags & ( FOG | SPECULAR ) ) { - normalEyeSpace.normalize_xyz(); - } + if ( !TransformationFlag [ETS_VIEW_INVERSE] ) + { + Transformation[ETS_VIEW_INVERSE] = Transformation[ ETS_VIEW ]; + Transformation[ETS_VIEW_INVERSE].makeInverse (); + TransformationFlag[ETS_VIEW_INVERSE] = 1; + } + const f32 *M = Transformation[ETS_VIEW_INVERSE].pointer (); + /* The viewpoint is at (0., 0., 0.) in eye space. + Turning this into a vector [0 0 0 1] and multiply it by + the inverse of the view matrix, the resulting vector is the + object space location of the camera. + */ + + eyeLightSpace.x = M[12]; + eyeLightSpace.y = M[13]; + eyeLightSpace.z = M[14]; + eyeLightSpace.w = 1.f; + } sVec4 ambient; sVec4 diffuse; @@ -1486,91 +1475,96 @@ void CBurningVideoDriver::lightVertex ( s4DVertex *dest, const S3DVertex *source diffuse.set ( 0.f, 0.f, 0.f, 0.f ); specular.set ( 0.f, 0.f, 0.f, 0.f ); - f32 attenuation = 1.f; u32 i; + f32 dot; + f32 len; + f32 attenuation; + sVec4 vp; // unit vector vertex to light + sVec4 lightHalf; // blinn-phong reflection + for ( i = 0; i!= LightSpace.Light.size (); ++i ) { const SBurningShaderLight &light = LightSpace.Light[i]; - sVec4 vp; // unit vector vertex to light - sVec4 lightHalf; // blinn-phong reflection - - switch ( light.org.Type ) { + case video::ELT_SPOT: case video::ELT_POINT: - { // surface to light - vp.x = light.posEyeSpace.x - vertexEyeSpace.x; - vp.y = light.posEyeSpace.y - vertexEyeSpace.y; - vp.z = light.posEyeSpace.z - vertexEyeSpace.z; + vp.x = light.posLightSpace.x - vertexLightSpace.x; + vp.y = light.posLightSpace.y - vertexLightSpace.y; + vp.z = light.posLightSpace.z - vertexLightSpace.z; - // irrlicht attenuation model -#if 0 - const f32 d = vp.get_inverse_length_xyz(); + len = vp.get_length_xyz_square(); + if ( light.org.Radius * light.org.Radius < len ) + continue; - vp.x *= d; - vp.y *= d; - vp.z *= d; - attenuation = light.org.Radius * d; + len = core::squareroot ( len ); + attenuation = light.constantAttenuation + + ( 1.f - (len * light.linearAttenuation) ); -#else - const f32 d = vp.get_length_xyz(); - attenuation = core::reciprocal (light.constantAttenuation + - light.linearAttenuation * d + - light.quadraticAttenuation * d * d - ); +/* + attenuation = light.constantAttenuation + + light.linearAttenuation * attenuation + + light.quadraticAttenuation * attenuation * attenuation; +*/ + // accumulate ambient + ambient += light.AmbientColor * attenuation; - // normalize surface to light - vp.normalize_xyz(); -#endif - lightHalf.x = vp.x - vertexEyeSpaceUnit.x; - lightHalf.y = vp.y - vertexEyeSpaceUnit.y; - lightHalf.z = vp.z - vertexEyeSpaceUnit.z; + // build diffuse reflection + + //angle between normal and light vector + vp *= core::reciprocal ( len ); + dot = normalLightSpace.dot_xyz ( vp ); + if ( dot < 0.f ) + continue; + + // diffuse component + diffuse += light.DiffuseColor * ( dot * attenuation ); + + if ( !(LightSpace.Flags & SPECULAR) ) + continue; + + // build specular + // surface to view + lightHalf.x = eyeLightSpace.x - vertexLightSpace.x; + lightHalf.y = eyeLightSpace.y - vertexLightSpace.y; + lightHalf.z = eyeLightSpace.z - vertexLightSpace.z; + lightHalf.normalize_xyz(); + lightHalf += vp; lightHalf.normalize_xyz(); - } break; + // specular + dot = normalLightSpace.dot_xyz ( lightHalf ); + if ( dot < 0.f ) + continue; + + //specular += light.SpecularColor * ( powf ( Material.org.Shininess ,dot ) * attenuation ); + specular += light.SpecularColor * ( dot * attenuation ); + break; case video::ELT_DIRECTIONAL: - { - attenuation = 1.f; - vp = light.posEyeSpace; - // half angle = lightvector + eye vector ( 0, 0, 1 ) - lightHalf.x = vp.x; - lightHalf.y = vp.y; - lightHalf.z = vp.z - 1.f; - lightHalf.normalize_xyz(); - } break; + // accumulate ambient + ambient += light.AmbientColor; + + //angle between normal and light vector + dot = normalLightSpace.dot_xyz ( light.posLightSpace ); + if ( dot < 0.f ) + continue; + + // diffuse component + diffuse += light.DiffuseColor * dot; + if ( !(LightSpace.Flags & SPECULAR) ) + continue; + break; } - // build diffuse reflection - - //angle between normal and light vector - f32 dotVP = core::max_ ( 0.f, normalEyeSpace.dot_xyz ( vp ) ); - f32 dotHV = core::max_ ( 0.f, normalEyeSpace.dot_xyz ( lightHalf ) ); - - f32 pf; - if ( dotVP == 0.0 ) - { - pf = 0.f; - } - else - { - pf = (f32)pow(dotHV, Material.org.Shininess ); - } - - // accumulate ambient - ambient += light.AmbientColor * attenuation; - diffuse += light.DiffuseColor * ( dotVP * attenuation ); - specular += light.SpecularColor * ( pf * attenuation ); - } - dColor = LightSpace.Global_AmbientLight; - dColor += Material.EmissiveColor; + // sum up lights dColor += ambient * Material.AmbientColor; dColor += diffuse * Material.DiffuseColor; dColor += specular * Material.SpecularColor; @@ -1857,13 +1851,13 @@ void CBurningVideoDriver::draw3DLine(const core::vector3df& start, const wchar_t* CBurningVideoDriver::getName() const { #ifdef BURNINGVIDEO_RENDERER_BEAUTIFUL - return L"burnings video 0.40b"; + return L"Burning's Video 0.42 beautiful"; #elif defined ( BURNINGVIDEO_RENDERER_ULTRA_FAST ) - return L"burnings video 0.40uf"; + return L"Burning's Video 0.42 ultra fast"; #elif defined ( BURNINGVIDEO_RENDERER_FAST ) - return L"burnings video 0.40f"; + return L"Burning's Video 0.42 fast"; #else - return L"burnings video 0.40"; + return L"Burning's Video 0.42"; #endif } diff --git a/source/Irrlicht/CSoftwareDriver2.h b/source/Irrlicht/CSoftwareDriver2.h index 03701e1d..fb05ab88 100644 --- a/source/Irrlicht/CSoftwareDriver2.h +++ b/source/Irrlicht/CSoftwareDriver2.h @@ -191,19 +191,18 @@ namespace video -> combined CameraProjectionWorld -> ClipScale from NDC to DC Space */ - enum E_TRANSFORMATION_STATE_2 + enum E_TRANSFORMATION_STATE_BURNING_VIDEO { ETS_VIEW_PROJECTION = ETS_COUNT, - ETS_WORLD_VIEW, - ETS_WORLD_VIEW_INVERSE_TRANSPOSED, ETS_CURRENT, ETS_CLIPSCALE, + ETS_VIEW_INVERSE, - ETS2_COUNT + ETS_COUNT_BURNING }; - u32 TransformationFlag[ETS2_COUNT]; - core::matrix4 Transformation[ETS2_COUNT]; + u32 TransformationFlag[ETS_COUNT_BURNING]; + core::matrix4 Transformation[ETS_COUNT_BURNING]; // Vertex Cache static const SVSize vSize[]; @@ -229,6 +228,9 @@ namespace video #ifdef SOFTWARE_DRIVER_2_LIGHTING void lightVertex ( s4DVertex *dest, const S3DVertex *source ); + //! Sets the fog mode. + virtual void setFog(SColor color, bool linearFog, f32 start, + f32 end, f32 density, bool pixelFog, bool rangeFog); #endif diff --git a/source/Irrlicht/CSoftwareTexture2.cpp b/source/Irrlicht/CSoftwareTexture2.cpp index 1b7f83b8..2aa58236 100644 --- a/source/Irrlicht/CSoftwareTexture2.cpp +++ b/source/Irrlicht/CSoftwareTexture2.cpp @@ -33,6 +33,12 @@ CSoftwareTexture2::CSoftwareTexture2(IImage* image, const core::string& nam { OrigSize = image->getDimension(); + core::setbit_cond ( Flags, + image->getColorFormat () == video::ECF_A8R8G8B8 || + image->getColorFormat () == video::ECF_A1R5G5B5, + HAS_ALPHA + ); + core::dimension2d optSize( OrigSize.getOptimalSize( 0 != ( Flags & NP2_SIZE ), false, false, diff --git a/source/Irrlicht/CSoftwareTexture2.h b/source/Irrlicht/CSoftwareTexture2.h index 75d51dd1..66eb338c 100644 --- a/source/Irrlicht/CSoftwareTexture2.h +++ b/source/Irrlicht/CSoftwareTexture2.h @@ -27,7 +27,8 @@ public: { GEN_MIPMAP = 1, IS_RENDERTARGET = 2, - NP2_SIZE = 4 + NP2_SIZE = 4, + HAS_ALPHA = 8 }; CSoftwareTexture2( IImage* surface, const core::string& name, u32 flags ); @@ -110,7 +111,13 @@ public: //! support mipmaps virtual bool hasMipMaps() const { - return Flags & GEN_MIPMAP; + return (Flags & GEN_MIPMAP ) != 0; + } + + //! Returns if the texture has an alpha channel + virtual bool hasAlpha() const + { + return (Flags & HAS_ALPHA ) != 0; } //! is a render target diff --git a/source/Irrlicht/CTRTextureBlend.cpp b/source/Irrlicht/CTRTextureBlend.cpp index 4857a9ed..c2823cc3 100644 --- a/source/Irrlicht/CTRTextureBlend.cpp +++ b/source/Irrlicht/CTRTextureBlend.cpp @@ -180,6 +180,11 @@ void CTRTextureBlend::setParam ( u32 index, f32 value) fragmentShader = &CTRTextureBlend::fragment_src_alpha_one; } else + if ( srcFact == EBF_SRC_COLOR && dstFact == EBF_SRC_ALPHA ) + { + fragmentShader = &CTRTextureBlend::fragment_src_color_src_alpha; + } + else { showname = 1; fragmentShader = &CTRTextureBlend::fragment_dst_color_zero; @@ -488,7 +493,7 @@ void CTRTextureBlend::fragment_src_color_src_alpha () f32 iw = FIX_POINT_F32_MUL; - tFixPoint a0, r0, g0, b0; + tFixPointu a0, r0, g0, b0; tFixPoint r1, g1, b1; s32 i; @@ -512,17 +517,13 @@ void CTRTextureBlend::fragment_src_color_src_alpha () iw = fix_inverse32 ( line.w[0] ); #endif - getSample_texture ( (tFixPointu&) a0, (tFixPointu&)r0, (tFixPointu&)g0, (tFixPointu&)b0, - &IT[0], - tofix ( line.t[0][0].x,iw), - tofix ( line.t[0][0].y,iw) - ); - + getSample_texture ( a0, r0, g0, b0, &IT[0], tofix ( line.t[0][0].x,iw), tofix ( line.t[0][0].y,iw) ); color_to_fix ( r1, g1, b1, dst[i] ); - dst[i] = fix_to_color ( clampfix_maxcolor ( imulFix_tex2 ( r0, r1 ) ), - clampfix_maxcolor ( imulFix_tex2 ( g0, g1 ) ), - clampfix_maxcolor ( imulFix_tex2 ( b0, b1 ) ) + u32 check = imulFix_tex1( r0, r1 ); + dst[i] = fix_to_color ( clampfix_maxcolor ( imulFix_tex1( r0, r1 ) + imulFix_tex1( r1, a0 ) ), + clampfix_maxcolor ( imulFix_tex1( g0, g1 ) + imulFix_tex1( g1, a0 ) ), + clampfix_maxcolor ( imulFix_tex1( b0, b1 ) + imulFix_tex1( b1, a0 ) ) ); } diff --git a/source/Irrlicht/CTRTextureGouraudAlphaNoZ.cpp b/source/Irrlicht/CTRTextureGouraudAlphaNoZ.cpp index cca68ee1..50818e19 100644 --- a/source/Irrlicht/CTRTextureGouraudAlphaNoZ.cpp +++ b/source/Irrlicht/CTRTextureGouraudAlphaNoZ.cpp @@ -33,7 +33,7 @@ #define CMP_W //#define WRITE_W -//#define IPOL_C0 +#define IPOL_C0 #define IPOL_T0 //#define IPOL_T1 @@ -147,7 +147,7 @@ void CTRTextureGouraudAlphaNoZ::scanline_bilinear () fp24 slopeW; #endif #ifdef IPOL_C0 - sVec4 slopeC; + sVec4 slopeC[MATERIAL_MAX_COLORS]; #endif #ifdef IPOL_T0 sVec2 slopeT[BURNING_MATERIAL_MAX_TEXTURES]; @@ -172,7 +172,7 @@ void CTRTextureGouraudAlphaNoZ::scanline_bilinear () slopeW = (line.w[1] - line.w[0]) * invDeltaX; #endif #ifdef IPOL_C0 - slopeC = (line.c[1] - line.c[0]) * invDeltaX; + slopeC[0] = (line.c[0][1] - line.c[0][0]) * invDeltaX; #endif #ifdef IPOL_T0 slopeT[0] = (line.t[0][1] - line.t[0][0]) * invDeltaX; @@ -190,7 +190,7 @@ void CTRTextureGouraudAlphaNoZ::scanline_bilinear () line.w[0] += slopeW * subPixel; #endif #ifdef IPOL_C0 - line.c[0] += slopeC * subPixel; + line.c[0][0] += slopeC[0] * subPixel; #endif #ifdef IPOL_T0 line.t[0][0] += slopeT[0] * subPixel; @@ -215,10 +215,14 @@ void CTRTextureGouraudAlphaNoZ::scanline_bilinear () u32 dIndex = ( line.y & 3 ) << 2; #else - tFixPointu a0; - tFixPointu r0, g0, b0; + tFixPoint a0; + tFixPoint r0, g0, b0; #endif +#ifdef IPOL_C0 + tFixPoint r1, g1, b1; + tFixPoint r2, g2, b2; +#endif for ( s32 i = 0; i <= dx; ++i ) { @@ -268,22 +272,20 @@ void CTRTextureGouraudAlphaNoZ::scanline_bilinear () #else #ifdef INVERSE_W - inversew = fix_inverse32 ( line.w[0] ); - - getSample_texture ( a0, r0, g0, b0, + getSample_texture ( (tFixPointu&) a0, (tFixPointu&) r0, (tFixPointu&)g0, (tFixPointu&)b0, &IT[0], tofix ( line.t[0][0].x,inversew), tofix ( line.t[0][0].y,inversew) ); #else - getSample_texture ( a0, r0, g0, b0, + getSample_texture ( (tFixPointu&) a0, (tFixPointu&) r0, (tFixPointu&)g0, (tFixPointu&)b0, &IT[0], tofix ( line.t[0][0].x), tofix ( line.t[0][0].y) ); #endif - if ( a0 > AlphaRef ) + if ( (tFixPointu) a0 > AlphaRef ) { #ifdef WRITE_Z z[i] = line.z[0]; @@ -292,10 +294,40 @@ void CTRTextureGouraudAlphaNoZ::scanline_bilinear () z[i] = line.w[0]; #endif +#ifdef INVERSE_W + getSample_color ( r2, g2, b2, line.c[0][0], inversew ); +#else + getSample_color ( r2, g2, b2, line.c[0][0] ); +#endif + r0 = imulFix ( r0, r2 ); + g0 = imulFix ( g0, g2 ); + b0 = imulFix ( b0, b2 ); + + color_to_fix ( r1, g1, b1, dst[i] ); + + a0 >>= 8; + + r2 = r1 + imulFix ( a0, r0 - r1 ); + g2 = g1 + imulFix ( a0, g0 - g1 ); + b2 = b1 + imulFix ( a0, b0 - b1 ); + dst[i] = fix4_to_color ( a0, r2, g2, b2 ); + +/* dst[i] = PixelBlend32 ( dst[i], fix_to_color ( r0,g0, b0 ), fixPointu_to_u32 ( a0 ) ); +*/ +/* + getSample_color ( r2, g2, b2, line.c[0][0], inversew * COLOR_MAX ); + color_to_fix ( r1, g1, b1, dst[i] ); + + r2 = r0 + imulFix ( a0, r1 - r0 ); + g2 = g0 + imulFix ( a0, g1 - g0 ); + b2 = b0 + imulFix ( a0, b1 - b0 ); + dst[i] = fix_to_color ( r2, g2, b2 ); +*/ + } #endif @@ -308,7 +340,7 @@ void CTRTextureGouraudAlphaNoZ::scanline_bilinear () line.w[0] += slopeW; #endif #ifdef IPOL_C0 - line.c[0] += slopeC; + line.c[0][0] += slopeC[0]; #endif #ifdef IPOL_T0 line.t[0][0] += slopeT[0]; @@ -363,8 +395,8 @@ void CTRTextureGouraudAlphaNoZ::drawTriangle ( const s4DVertex *a,const s4DVerte #endif #ifdef IPOL_C0 - scan.slopeC[0] = (c->Color[0] - a->Color[0]) * scan.invDeltaY[0]; - scan.c[0] = a->Color[0]; + scan.slopeC[0][0] = (c->Color[0] - a->Color[0]) * scan.invDeltaY[0]; + scan.c[0][0] = a->Color[0]; #endif #ifdef IPOL_T0 @@ -385,7 +417,6 @@ void CTRTextureGouraudAlphaNoZ::drawTriangle ( const s4DVertex *a,const s4DVerte f32 subPixel; #endif - #ifdef IPOL_T0 IT[0].data = (tVideoSample*)IT[0].Texture->lock(); #endif @@ -412,8 +443,8 @@ void CTRTextureGouraudAlphaNoZ::drawTriangle ( const s4DVertex *a,const s4DVerte #endif #ifdef IPOL_C0 - scan.slopeC[1] = (b->Color[0] - a->Color[0]) * scan.invDeltaY[1]; - scan.c[1] = a->Color[0]; + scan.slopeC[0][1] = (b->Color[0] - a->Color[0]) * scan.invDeltaY[1]; + scan.c[0][1] = a->Color[0]; #endif #ifdef IPOL_T0 @@ -448,8 +479,8 @@ void CTRTextureGouraudAlphaNoZ::drawTriangle ( const s4DVertex *a,const s4DVerte #endif #ifdef IPOL_C0 - scan.c[0] += scan.slopeC[0] * subPixel; - scan.c[1] += scan.slopeC[1] * subPixel; + scan.c[0][0] += scan.slopeC[0][0] * subPixel; + scan.c[0][1] += scan.slopeC[0][1] * subPixel; #endif #ifdef IPOL_T0 @@ -481,8 +512,8 @@ void CTRTextureGouraudAlphaNoZ::drawTriangle ( const s4DVertex *a,const s4DVerte #endif #ifdef IPOL_C0 - line.c[scan.left] = scan.c[0]; - line.c[scan.right] = scan.c[1]; + line.c[0][scan.left] = scan.c[0][0]; + line.c[0][scan.right] = scan.c[0][1]; #endif #ifdef IPOL_T0 @@ -512,8 +543,8 @@ void CTRTextureGouraudAlphaNoZ::drawTriangle ( const s4DVertex *a,const s4DVerte #endif #ifdef IPOL_C0 - scan.c[0] += scan.slopeC[0]; - scan.c[1] += scan.slopeC[1]; + scan.c[0][0] += scan.slopeC[0][0]; + scan.c[0][1] += scan.slopeC[0][1]; #endif #ifdef IPOL_T0 @@ -545,7 +576,7 @@ void CTRTextureGouraudAlphaNoZ::drawTriangle ( const s4DVertex *a,const s4DVerte scan.w[0] = a->Pos.w + scan.slopeW[0] * temp[0]; #endif #ifdef IPOL_C0 - scan.c[0] = a->Color[0] + scan.slopeC[0] * temp[0]; + scan.c[0][0] = a->Color[0] + scan.slopeC[0][0] * temp[0]; #endif #ifdef IPOL_T0 scan.t[0][0] = a->Tex[0] + scan.slopeT[0][0] * temp[0]; @@ -571,8 +602,8 @@ void CTRTextureGouraudAlphaNoZ::drawTriangle ( const s4DVertex *a,const s4DVerte #endif #ifdef IPOL_C0 - scan.slopeC[1] = (c->Color[0] - b->Color[0]) * scan.invDeltaY[2]; - scan.c[1] = b->Color[0]; + scan.slopeC[0][1] = (c->Color[0] - b->Color[0]) * scan.invDeltaY[2]; + scan.c[0][1] = b->Color[0]; #endif #ifdef IPOL_T0 @@ -608,8 +639,8 @@ void CTRTextureGouraudAlphaNoZ::drawTriangle ( const s4DVertex *a,const s4DVerte #endif #ifdef IPOL_C0 - scan.c[0] += scan.slopeC[0] * subPixel; - scan.c[1] += scan.slopeC[1] * subPixel; + scan.c[0][0] += scan.slopeC[0][0] * subPixel; + scan.c[0][1] += scan.slopeC[0][1] * subPixel; #endif #ifdef IPOL_T0 @@ -641,8 +672,8 @@ void CTRTextureGouraudAlphaNoZ::drawTriangle ( const s4DVertex *a,const s4DVerte #endif #ifdef IPOL_C0 - line.c[scan.left] = scan.c[0]; - line.c[scan.right] = scan.c[1]; + line.c[0][scan.left] = scan.c[0][0]; + line.c[0][scan.right] = scan.c[0][1]; #endif #ifdef IPOL_T0 @@ -672,8 +703,8 @@ void CTRTextureGouraudAlphaNoZ::drawTriangle ( const s4DVertex *a,const s4DVerte #endif #ifdef IPOL_C0 - scan.c[0] += scan.slopeC[0]; - scan.c[1] += scan.slopeC[1]; + scan.c[0][0] += scan.slopeC[0][0]; + scan.c[0][1] += scan.slopeC[0][1]; #endif #ifdef IPOL_T0 @@ -705,6 +736,7 @@ void CTRTextureGouraudAlphaNoZ::drawTriangle ( const s4DVertex *a,const s4DVerte } + } // end namespace video } // end namespace irr @@ -715,6 +747,7 @@ namespace irr namespace video { + //! creates a flat triangle renderer IBurningShader* createTRTextureGouraudAlphaNoZ(IDepthBuffer* zbuffer) { diff --git a/source/Irrlicht/CZipReader.cpp b/source/Irrlicht/CZipReader.cpp index fb49dbd7..03fc73ca 100644 --- a/source/Irrlicht/CZipReader.cpp +++ b/source/Irrlicht/CZipReader.cpp @@ -41,7 +41,7 @@ CArchiveLoaderZIP::~CArchiveLoaderZIP() //! returns true if the file maybe is able to be loaded by this class bool CArchiveLoaderZIP::isALoadableFileFormat(const core::string& filename) const { - return core::hasFileExtension ( filename, "zip", "pk3" ); + return core::hasFileExtension ( filename, "zip", "pk3", "dat" ); } @@ -582,12 +582,8 @@ CMountPointReader::CMountPointReader( IFileSystem * parent, const core::string Light; sVec4 Global_AmbientLight; + sVec4 FogColor; + u32 Flags; }; struct SBurningShaderMaterial @@ -56,7 +74,6 @@ namespace video sVec4 SpecularColor; sVec4 EmissiveColor; - u32 SpecularEnabled; // == Power2 }; enum EBurningFFShader diff --git a/source/Irrlicht/Irrlicht8.0.vcproj b/source/Irrlicht/Irrlicht8.0.vcproj index 278abd77..5b95f418 100644 --- a/source/Irrlicht/Irrlicht8.0.vcproj +++ b/source/Irrlicht/Irrlicht8.0.vcproj @@ -689,6 +689,10 @@ RelativePath=".\..\..\include\SMaterial.h" > + + + + @@ -1141,6 +1149,10 @@ RelativePath=".\..\..\include\IGUIFont.h" > + + @@ -1185,6 +1197,10 @@ RelativePath=".\..\..\include\IGUITabControl.h" > + + diff --git a/source/Irrlicht/OctTree.h b/source/Irrlicht/OctTree.h index 889f5d92..242a6b92 100644 --- a/source/Irrlicht/OctTree.h +++ b/source/Irrlicht/OctTree.h @@ -12,10 +12,11 @@ #include "CMeshBuffer.h" /*! - if defined OCTTREE_USE_HARDWARE octree uses interally a derived scene::CMeshBuffer + Flags for Octtree */ -#define OCTTREE_USE_HARDWARE -#define OCTTREE_PARENTTEST +#define OCTTREE_USE_HARDWARE // use meshbuffer for drawing, enables hardware acceleration +#define OCTTREE_PARENTTEST // bypass full invisible/visible test +#define OCTTREE_BOX_BASED // use bounding box or frustum for calculate polys namespace irr { @@ -276,6 +277,7 @@ private: // by this bounding box. void getPolys(const core::aabbox3d& box, SIndexData* idxdata, u32 parentTest ) const { +#if defined (OCTTREE_PARENTTEST ) // if not full inside if ( parentTest != 2 ) { @@ -286,8 +288,9 @@ private: // fully inside ? parentTest = Box.isFullInside(box)?2:1; } - - //if (Box.intersectsWithBox(box)) +#else + if (Box.intersectsWithBox(box)) +#endif { const u32 cnt = IndexData->size(); u32 i; // new ISO for scoping problem in some compilers diff --git a/source/Irrlicht/S4DVertex.h b/source/Irrlicht/S4DVertex.h index 6c34d769..8511b0b3 100644 --- a/source/Irrlicht/S4DVertex.h +++ b/source/Irrlicht/S4DVertex.h @@ -141,10 +141,16 @@ struct sVec4 void saturate () { + x = core::min_ ( x, 1.f ); + y = core::min_ ( y, 1.f ); + z = core::min_ ( z, 1.f ); + w = core::min_ ( w, 1.f ); +/* x = core::clamp ( x, 0.f, 1.f ); y = core::clamp ( y, 0.f, 1.f ); z = core::clamp ( z, 0.f, 1.f ); w = core::clamp ( w, 0.f, 1.f ); +*/ } // f = a * t + b * ( 1 - t ) @@ -167,9 +173,14 @@ struct sVec4 return x*other.x + y*other.y + z*other.z; } + f32 get_length_xyz_square () const + { + return x * x + y * y + z * z; + } + f32 get_length_xyz () const { - return sqrtf ( x * x + y * y + z * z ); + return core::squareroot ( x * x + y * y + z * z ); } f32 get_inverse_length_xyz () const diff --git a/source/Irrlicht/os.cpp b/source/Irrlicht/os.cpp index 3d8d4585..929186a7 100644 --- a/source/Irrlicht/os.cpp +++ b/source/Irrlicht/os.cpp @@ -73,7 +73,7 @@ namespace os tmp += L"\n"; OutputDebugStringW( tmp.c_str() ); #else - c8* tmp = new c8[strlen(message) + 2]; + c8* tmp = new c8[strlen(message) + 4]; sprintf(tmp, "%s\n", message); OutputDebugString(tmp); printf(tmp);