From fec90122c3deedf9369295f02cf51d669dd66d4f Mon Sep 17 00:00:00 2001 From: Star-Demon Date: Sun, 2 Jan 2011 11:55:00 -0500 Subject: [PATCH 01/62] Added enumerated States to inputmanager to handle future standard actions. --- apps/openmw/mwinput/inputmanager.cpp | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/apps/openmw/mwinput/inputmanager.cpp b/apps/openmw/mwinput/inputmanager.cpp index 0544df6f0..c5353d7b1 100644 --- a/apps/openmw/mwinput/inputmanager.cpp +++ b/apps/openmw/mwinput/inputmanager.cpp @@ -45,6 +45,24 @@ namespace MWInput A_Activate, + A_Use, //Use weapon, spell, etc. + A_Jump, + A_AutoMove, //Toggle Auto-move forward + A_Rest, //Rest + A_Journal, //Journal + A_Weapon, //Draw/Sheath weapon + A_Spell, //Ready/Unready Casting + A_AlwaysRun, //Toggle Always Run + A_CycleSpellLeft, //cycling through spells + A_CycleSPellRight, + A_CycleWeaponLeft,//Cycling through weapons + A_CycleWeaponRight, + + A_QuickSave, + A_QuickLoad, + A_QuickMenu, + A_GameMenu, + A_LAST // Marker for the last item }; From e98eef8cd31c624a4f47207ed2de84dca09af4c5 Mon Sep 17 00:00:00 2001 From: Star-Demon Date: Sun, 9 Jan 2011 16:42:38 -0500 Subject: [PATCH 02/62] corrected grammar for merge --- apps/openmw/mwinput/inputmanager.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/apps/openmw/mwinput/inputmanager.cpp b/apps/openmw/mwinput/inputmanager.cpp index c5353d7b1..69c644046 100644 --- a/apps/openmw/mwinput/inputmanager.cpp +++ b/apps/openmw/mwinput/inputmanager.cpp @@ -54,7 +54,7 @@ namespace MWInput A_Spell, //Ready/Unready Casting A_AlwaysRun, //Toggle Always Run A_CycleSpellLeft, //cycling through spells - A_CycleSPellRight, + A_CycleSpellRight, A_CycleWeaponLeft,//Cycling through weapons A_CycleWeaponRight, @@ -86,8 +86,8 @@ namespace MWInput // Write screenshot to file. void screenshot() { - // Find the first unused filename. - // + + // Find the first unused filename with a do-while char buf[50]; do { From 3ab4a4487f9fb59597f917c406552544c29cf3d3 Mon Sep 17 00:00:00 2001 From: Star-Demon Date: Wed, 12 Jan 2011 12:19:33 -0500 Subject: [PATCH 03/62] Sneak State, Bound Sneak and AutoMove, began outlining AutoMove --- apps/openmw/mwinput/inputmanager.cpp | 13 +++++++++++++ libs/mangle | 2 +- libs/openengine | 2 +- 3 files changed, 15 insertions(+), 2 deletions(-) diff --git a/apps/openmw/mwinput/inputmanager.cpp b/apps/openmw/mwinput/inputmanager.cpp index 15d6f5e0f..c93ce1611 100644 --- a/apps/openmw/mwinput/inputmanager.cpp +++ b/apps/openmw/mwinput/inputmanager.cpp @@ -60,6 +60,7 @@ namespace MWInput A_CycleSpellRight, A_CycleWeaponLeft,//Cycling through weapons A_CycleWeaponRight, + A_ToggleSneak, //Toggles Sneak, add Push-Sneak later A_QuickSave, A_QuickLoad, @@ -213,6 +214,7 @@ namespace MWInput **********************************/ // Key bindings for keypress events + // NOTE: These keys do not require constant polling - use in conjuction with variables in loops. disp->bind(A_Quit, KC_Q); disp->bind(A_Quit, KC_ESCAPE); @@ -220,8 +222,11 @@ namespace MWInput disp->bind(A_Inventory, KC_I); disp->bind(A_Console, KC_F1); disp->bind(A_Activate, KC_SPACE); + disp->bind(A_AutoMove, KC_Z); + disp->bind(A_ToggleSneak, KC_X); // Key bindings for polled keys + // NOTE: These keys are constantly being polled. Only add keys that must be checked each frame. // Arrow keys poller.bind(A_MoveLeft, KC_LEFT); @@ -259,6 +264,14 @@ namespace MWInput float speed = 300 * evt.timeSinceLastFrame; float moveX = 0, moveY = 0, moveZ = 0; + + + //TODO: Where should I put bool isAutoMoving; ? + //AUTO-MOVE condition + //Check Automove Toggle. + //If true...apply current MoveType speed to current direction + + //If any other movement key is pressed, Toggle automove. if(poller.isDown(A_MoveLeft)) moveX -= speed; if(poller.isDown(A_MoveRight)) moveX += speed; diff --git a/libs/mangle b/libs/mangle index 12e5c8d70..7345f2307 160000 --- a/libs/mangle +++ b/libs/mangle @@ -1 +1 @@ -Subproject commit 12e5c8d704b959c78a62931b2360d18092b82c3d +Subproject commit 7345f2307f3ce6682a4044b98a811fac2cb7c4f0 diff --git a/libs/openengine b/libs/openengine index 7185eab18..377e7d71c 160000 --- a/libs/openengine +++ b/libs/openengine @@ -1 +1 @@ -Subproject commit 7185eab18c29a0a5e03e44690d6bd8ece7e3792b +Subproject commit 377e7d71ceea5a1ca166b8df9a03a5b68df83bc5 From a8ade56c80cbf64e45f6b40b1f3b1250ad95cc82 Mon Sep 17 00:00:00 2001 From: gugus Date: Thu, 13 Jan 2011 17:51:50 +0100 Subject: [PATCH 04/62] Add a bullet Shape Loader --- CMakeLists.txt | 6 + components/nif/nif_file.cpp | 3 +- components/nif/record.hpp | 3 +- components/nifbullet/bullet_nif_loader.cpp | 386 +++++++++++++++++++++ components/nifbullet/bullet_nif_loader.hpp | 236 +++++++++++++ components/nifbullet/test/test.cpp | 209 +++++++++++ 6 files changed, 841 insertions(+), 2 deletions(-) create mode 100644 components/nifbullet/bullet_nif_loader.cpp create mode 100644 components/nifbullet/bullet_nif_loader.hpp create mode 100644 components/nifbullet/test/test.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index b5dcdbb47..63c65381b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -81,6 +81,12 @@ set(NIFOGRE_HEADER ${COMP_DIR}/nifogre/ogre_nif_loader.hpp) source_group(components\\nifogre FILES ${NIFOGRE} ${NIFOGRE_HEADER}) +set(NIFBULLET + ${COMP_DIR}/nifbullet/ogre_bullet_loader.cpp) +set(NIFBULLET_HEADER + ${COMP_DIR}/nifbullet/bullet_nif_loader.hpp) +source_group(components\\nifbullet FILES ${NIFBULLET} ${NIFBULLET_HEADER}) + set(TO_UTF8 ${COMP_DIR}/to_utf8/to_utf8.cpp) set(TO_UTF8_HEADER diff --git a/components/nif/nif_file.cpp b/components/nif/nif_file.cpp index fb1b988a7..6a4eb337c 100644 --- a/components/nif/nif_file.cpp +++ b/components/nif/nif_file.cpp @@ -83,7 +83,6 @@ void NIFFile::parse() // NiNodes if(rec == "NiNode" || rec == "AvoidNode" || - rec == "RootCollisionNode" || rec == "NiBSParticleNode" || rec == "NiBSAnimationNode" || rec == "NiBillboardNode") { r = new NiNode; r->recType = RC_NiNode; } @@ -93,6 +92,8 @@ void NIFFile::parse() else if(rec == "NiRotatingParticles") { r = new NiRotatingParticles; r->recType = RC_NiRotatingParticles; } else if(rec == "NiAutoNormalParticles") { r = new NiAutoNormalParticles; r->recType = RC_NiAutoNormalParticles; } else if(rec == "NiCamera") { r = new NiCamera; r->recType = RC_NiCamera; } + else if(rec == "RootCollisionNode"){ r = new NiNode; r->recType = RC_RootCollisionNode; }// a root collision node is exactly like a node + //that's why there is no need to create a new type // Properties else if(rec == "NiTexturingProperty") { r = new NiTexturingProperty; r->recType = RC_NiTexturingProperty; } diff --git a/components/nif/record.hpp b/components/nif/record.hpp index 9be3faf8d..8b8910118 100644 --- a/components/nif/record.hpp +++ b/components/nif/record.hpp @@ -79,7 +79,8 @@ enum RecordType RC_NiAutoNormalParticlesData, RC_NiSequenceStreamHelper, RC_NiSourceTexture, - RC_NiSkinInstance + RC_NiSkinInstance, + RC_RootCollisionNode }; /// Base class for all records diff --git a/components/nifbullet/bullet_nif_loader.cpp b/components/nifbullet/bullet_nif_loader.cpp new file mode 100644 index 000000000..6ce26e8a5 --- /dev/null +++ b/components/nifbullet/bullet_nif_loader.cpp @@ -0,0 +1,386 @@ +/* +OpenMW - The completely unofficial reimplementation of Morrowind +Copyright (C) 2008-2010 Nicolay Korslund +Email: < korslund@gmail.com > +WWW: http://openmw.sourceforge.net/ + +This file (ogre_nif_loader.cpp) is part of the OpenMW package. + +OpenMW is distributed as free software: you can redistribute it +and/or modify it under the terms of the GNU General Public License +version 3, as published by the Free Software Foundation. + +This program is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +version 3 along with this program. If not, see +http://www.gnu.org/licenses/ . + +*/ + +#include "bullet_nif_loader.hpp" +#include +#include + +#include +#include "../nif/nif_file.hpp" +#include "../nif/node.hpp" +#include "../nif/data.hpp" +#include "../nif/property.hpp" +#include "../nif/controller.hpp" +#include "../nif/extra.hpp" +#include + +#include +#include +// For warning messages +#include + +// float infinity +#include + +typedef unsigned char ubyte; + +using namespace std; +using namespace Ogre; +using namespace Nif; +using namespace Mangle::VFS; + + +BulletShape::BulletShape(Ogre::ResourceManager* creator, const Ogre::String &name, + Ogre::ResourceHandle handle, const Ogre::String &group, bool isManual, + Ogre::ManualResourceLoader *loader) : +Ogre::Resource(creator, name, handle, group, isManual, loader) +{ + /* If you were storing a pointer to an object, then you would set that pointer to NULL here. + */ + + /* For consistency with StringInterface, but we don't add any parameters here + That's because the Resource implementation of StringInterface is to + list all the options that need to be set before loading, of which + we have none as such. Full details can be set through scripts. + */ + Shape = NULL; + createParamDictionary("BulletShape"); +} + +BulletShape::~BulletShape() +{ +} + +// farm out to BulletShapeLoader +void BulletShape::loadImpl() +{ + mLoader->loadResource(this); +} + +void BulletShape::deleteShape(btCollisionShape* mShape) +{ + if(mShape!=NULL) + { + if(mShape->isCompound()) + { + btCompoundShape* ms = static_cast(Shape); + btCompoundShapeChild* child = ms->getChildList(); + int a = ms->getNumChildShapes(); + for(int i=0; i getChildShape(i)); + } + } + delete mShape; + } + mShape = NULL; +} + +void BulletShape::unloadImpl() +{ + deleteShape(Shape); +} + +//TODO:change this? +size_t BulletShape::calculateSize() const +{ + return 1; +} + + +//============================================================================================================= +template<> BulletShapeManager *Ogre::Singleton::ms_Singleton = 0; + +BulletShapeManager *BulletShapeManager::getSingletonPtr() +{ + return ms_Singleton; +} + +BulletShapeManager &BulletShapeManager::getSingleton() +{ + assert(ms_Singleton); + return(*ms_Singleton); +} + +BulletShapeManager::BulletShapeManager() +{ + mResourceType = "BulletShape"; + + // low, because it will likely reference other resources + mLoadOrder = 30.0f; + + // this is how we register the ResourceManager with OGRE + Ogre::ResourceGroupManager::getSingleton()._registerResourceManager(mResourceType, this); +} + +BulletShapeManager::~BulletShapeManager() +{ + // and this is how we unregister it + Ogre::ResourceGroupManager::getSingleton()._unregisterResourceManager(mResourceType); +} + +BulletShapePtr BulletShapeManager::load(const Ogre::String &name, const Ogre::String &group) +{ + BulletShapePtr textf = getByName(name); + + if (textf.isNull()) + textf = create(name, group); + + textf->load(); + return textf; +} + +Ogre::Resource *BulletShapeManager::createImpl(const Ogre::String &name, Ogre::ResourceHandle handle, + const Ogre::String &group, bool isManual, Ogre::ManualResourceLoader *loader, + const Ogre::NameValuePairList *createParams) +{ + BulletShape* res = new BulletShape(this, name, handle, group, isManual, loader); + //if(isManual) + //{ + //loader->loadResource(res); + //} + return res; +} + +//==================================================================================================== +Ogre::Matrix3 ManualBulletShapeLoader::getMatrix(Nif::Transformation* tr) +{ + Ogre::Matrix3 rot(tr->rotation.v[0].array[0],tr->rotation.v[0].array[1],tr->rotation.v[0].array[2], + tr->rotation.v[1].array[0],tr->rotation.v[1].array[1],tr->rotation.v[1].array[2], + tr->rotation.v[2].array[0],tr->rotation.v[2].array[1],tr->rotation.v[2].array[2]); + return rot; +} +Ogre::Vector3 ManualBulletShapeLoader::getVector(Nif::Transformation* tr) +{ + Ogre::Vector3 vect3(tr->pos.array[0],tr->pos.array[1],tr->pos.array[2]); + return vect3; +} + +btQuaternion ManualBulletShapeLoader::getbtQuat(Ogre::Matrix3 m) +{ + Ogre::Quaternion oquat(m); + btQuaternion quat; + quat.setW(oquat.w); + quat.setX(oquat.x); + quat.setY(oquat.y); + quat.setZ(oquat.z); + return quat; +} + +btVector3 ManualBulletShapeLoader::getbtVector(Nif::Vector v) +{ + btVector3 a(v.array[0],v.array[1],v.array[2]); + return a; +} + +void ManualBulletShapeLoader::loadResource(Ogre::Resource *resource) +{ + cShape = static_cast(resource); + resourceName = cShape->getName(); + + currentShape = new btCompoundShape(); + cShape->Shape = currentShape; + + if (!vfs) vfs = new OgreVFS(resourceGroup); + + if (!vfs->isFile(resourceName)) + { + warn("File not found."); + return; + } + + // Load the NIF. TODO: Wrap this in a try-catch block once we're out + // of the early stages of development. Right now we WANT to catch + // every error as early and intrusively as possible, as it's most + // likely a sign of incomplete code rather than faulty input. + Nif::NIFFile nif(vfs->open(resourceName), resourceName); + + if (nif.numRecords() < 1) + { + warn("Found no records in NIF."); + return; + } + + + // The first record is assumed to be the root node + Nif::Record *r = nif.getRecord(0); + assert(r != NULL); + + Nif::Node *node = dynamic_cast(r); + + if (node == NULL) + { + warn("First record in file was not a node, but a " + + r->recName.toString() + ". Skipping file."); + return; + } + + handleNode(node,0,Ogre::Matrix3::IDENTITY,Ogre::Vector3::ZERO,1,false); +} + +void ManualBulletShapeLoader::handleNode(Nif::Node *node, int flags, + Ogre::Matrix3 parentRot,Ogre::Vector3 parentPos,float parentScale,bool isCollisionNode) +{ + // Accumulate the flags from all the child nodes. This works for all + // the flags we currently use, at least. + flags |= node->flags; + + // Check for extra data + Nif::Extra *e = node; + while (!e->extra.empty()) + { + // Get the next extra data in the list + e = e->extra.getPtr(); + assert(e != NULL); + + if (e->recType == Nif::RC_NiStringExtraData) + { + // String markers may contain important information + // affecting the entire subtree of this node + Nif::NiStringExtraData *sd = (Nif::NiStringExtraData*)e; + + if (sd->string == "NCO") + { + // No collision. Use an internal flag setting to mark this. + // We ignor this node! + flags |= 0x800; + return; + } + else if (sd->string == "MRK") + // Marker objects. These are only visible in the + // editor. Until and unless we add an editor component to + // the engine, just skip this entire node. + return; + } + } + + //transfo of parents node + curent node + Ogre::Matrix3 finalRot; + Ogre::Vector3 finalPos; + float finalScale; + + Nif::Transformation &final = *((Nif::Transformation*)node->trafo); + Ogre::Vector3 nodePos = getVector(&final); + Ogre::Matrix3 nodeRot = getMatrix(&final); + + finalPos = nodePos + parentPos; + finalRot = parentRot*nodeRot; + finalScale = final.scale*parentScale; + + + // For NiNodes, loop through children + if (node->recType == Nif::RC_NiNode) + { + Nif::NodeList &list = ((Nif::NiNode*)node)->children; + int n = list.length(); + for (int i=0; irecType == Nif::RC_NiTriShape && isCollisionNode) handleNiTriShape(dynamic_cast(node), flags,finalRot,finalPos,finalScale); + else if(node->recType = Nif::RC_RootCollisionNode) + { + Nif::NodeList &list = ((Nif::NiNode*)node)->children; + int n = list.length(); + for (int i=0; i