Merge remote branch 'zini/master' into nif-cleanup

Conflicts:
	components/nifbullet/bullet_nif_loader.cpp
actorid
Chris Robinson 13 years ago
commit 348b5fa207

@ -39,7 +39,7 @@ add_openmw_dir (mwscript
locals scriptmanager compilercontext interpretercontext cellextensions miscextensions locals scriptmanager compilercontext interpretercontext cellextensions miscextensions
guiextensions soundextensions skyextensions statsextensions containerextensions guiextensions soundextensions skyextensions statsextensions containerextensions
aiextensions controlextensions extensions globalscripts ref dialogueextensions aiextensions controlextensions extensions globalscripts ref dialogueextensions
animationextensions animationextensions transformationextensions
) )
add_openmw_dir (mwsound add_openmw_dir (mwsound

@ -178,6 +178,10 @@ namespace MWBase
virtual void moveObject (const MWWorld::Ptr& ptr, float x, float y, float z) = 0; virtual void moveObject (const MWWorld::Ptr& ptr, float x, float y, float z) = 0;
virtual void scaleObject (const MWWorld::Ptr& ptr, float scale) = 0;
virtual void rotateObject(const MWWorld::Ptr& ptr,float x,float y,float z) = 0;
virtual void indexToPosition (int cellX, int cellY, float &x, float &y, bool centre = false) virtual void indexToPosition (int cellX, int cellY, float &x, float &y, bool centre = false)
const = 0; const = 0;
///< Convert cell numbers to position. ///< Convert cell numbers to position.

@ -125,10 +125,14 @@ namespace MWClass
void Npc::insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const void Npc::insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const
{ {
MWWorld::LiveCellRef<ESM::NPC> *ref = MWWorld::LiveCellRef<ESM::NPC> *ref =
ptr.get<ESM::NPC>(); ptr.get<ESM::NPC>();
assert (ref->base != NULL); assert (ref->base != NULL);
std::string headID = ref->base->head; std::string headID = ref->base->head;
std::string bodyRaceID = headID.substr(0, headID.find_last_of("head_") - 4); std::string bodyRaceID = headID.substr(0, headID.find_last_of("head_") - 4);
bool beast = bodyRaceID == "b_n_khajiit_m_" || bodyRaceID == "b_n_khajiit_f_" || bodyRaceID == "b_n_argonian_m_" || bodyRaceID == "b_n_argonian_f_"; bool beast = bodyRaceID == "b_n_khajiit_m_" || bodyRaceID == "b_n_khajiit_f_" || bodyRaceID == "b_n_argonian_m_" || bodyRaceID == "b_n_argonian_f_";
@ -136,7 +140,8 @@ namespace MWClass
std::string smodel = "meshes\\base_anim.nif"; std::string smodel = "meshes\\base_anim.nif";
if(beast) if(beast)
smodel = "meshes\\base_animkna.nif"; smodel = "meshes\\base_animkna.nif";
physics.insertActorPhysics(ptr, smodel); physics.insertActorPhysics(ptr, smodel);
MWBase::Environment::get().getMechanicsManager()->addActor (ptr); MWBase::Environment::get().getMechanicsManager()->addActor (ptr);
} }
@ -342,4 +347,11 @@ namespace MWClass
return weight; return weight;
} }
void Npc::adjustRotation(const MWWorld::Ptr& ptr,float& x,float& y,float& z) const
{
y = 0;
x = 0;
std::cout << "dfdfdfdfnzdofnmqsldgnmqskdhblqkdbv lqksdf";
}
} }

@ -76,6 +76,8 @@ namespace MWClass
///< Returns total weight of objects inside this object (including modifications from magic ///< Returns total weight of objects inside this object (including modifications from magic
/// effects). Throws an exception, if the object can't hold other objects. /// effects). Throws an exception, if the object can't hold other objects.
virtual void adjustRotation(const MWWorld::Ptr& ptr,float& x,float& y,float& z) const;
static void registerSelf(); static void registerSelf();
}; };
} }

@ -706,7 +706,7 @@ namespace MWDialogue
} }
return false; return false;
} }
catch (const Compiler::SourceException& error) catch (const Compiler::SourceException& /* error */)
{ {
// error has already been reported via error handler // error has already been reported via error handler
} }

@ -286,7 +286,7 @@ void HUD::onWorldClicked(MyGUI::Widget* _sender)
{ {
object = MWBase::Environment::get().getWorld()->getPtrViaHandle(handle); object = MWBase::Environment::get().getWorld()->getPtrViaHandle(handle);
} }
catch (std::exception& e) catch (std::exception& /* e */)
{ {
return; return;
} }

@ -310,6 +310,9 @@ namespace MWGui
&& (type != typeid(ESM::Potion).name())) && (type != typeid(ESM::Potion).name()))
return; return;
if (MWWorld::Class::get(object).getName(object) == "") // objects without name presented to user can never be picked up
return;
// sound // sound
std::string sound = MWWorld::Class::get(object).getUpSoundId(object); std::string sound = MWWorld::Class::get(object).getUpSoundId(object);
MWBase::Environment::get().getSoundManager()->playSound(sound, 1, 1); MWBase::Environment::get().getSoundManager()->playSound(sound, 1, 1);

@ -12,6 +12,10 @@ namespace MWGui
{ {
} }
ReferenceInterface::~ReferenceInterface()
{
}
void ReferenceInterface::checkReferenceAvailable() void ReferenceInterface::checkReferenceAvailable()
{ {
if (mPtr.isEmpty()) if (mPtr.isEmpty())

@ -13,6 +13,7 @@ namespace MWGui
{ {
public: public:
ReferenceInterface(); ReferenceInterface();
virtual ~ReferenceInterface();
void checkReferenceAvailable(); ///< closes the window, if the MW-reference has become unavailable void checkReferenceAvailable(); ///< closes the window, if the MW-reference has become unavailable

@ -81,7 +81,7 @@ void ToolTips::onFrame(float frameDuration)
{ {
mFocusObject = MWBase::Environment::get().getWorld()->getPtrViaHandle(handle); mFocusObject = MWBase::Environment::get().getWorld()->getPtrViaHandle(handle);
} }
catch (std::exception& e) catch (std::exception /* & e */)
{ {
return; return;
} }

@ -165,4 +165,9 @@ op 0x2000160: SetFlee
op 0x2000161: SetFlee, explicit reference op 0x2000161: SetFlee, explicit reference
op 0x2000162: SetAlarm op 0x2000162: SetAlarm
op 0x2000163: SetAlarm, explicit reference op 0x2000163: SetAlarm, explicit reference
opcodes 0x2000164-0x3ffffff unused op 0x2000164: SetScale
op 0x2000165: SetScale, explicit reference
op 0x2000166: SetAngle
op 0x2000167: SetAngle, explicit reference
opcodes 0x2000168-0x3ffffff unused

@ -15,6 +15,7 @@
#include "controlextensions.hpp" #include "controlextensions.hpp"
#include "dialogueextensions.hpp" #include "dialogueextensions.hpp"
#include "animationextensions.hpp" #include "animationextensions.hpp"
#include "transformationextensions.hpp"
namespace MWScript namespace MWScript
{ {
@ -31,6 +32,7 @@ namespace MWScript
Control::registerExtensions (extensions); Control::registerExtensions (extensions);
Dialogue::registerExtensions (extensions); Dialogue::registerExtensions (extensions);
Animation::registerExtensions (extensions); Animation::registerExtensions (extensions);
Transformation::registerExtensions (extensions);
} }
void installOpcodes (Interpreter::Interpreter& interpreter) void installOpcodes (Interpreter::Interpreter& interpreter)
@ -47,5 +49,6 @@ namespace MWScript
Control::installOpcodes (interpreter); Control::installOpcodes (interpreter);
Dialogue::installOpcodes (interpreter); Dialogue::installOpcodes (interpreter);
Animation::installOpcodes (interpreter); Animation::installOpcodes (interpreter);
Transformation::installOpcodes (interpreter);
} }
} }

@ -505,6 +505,7 @@ namespace MWScript
} }
}; };
const int numberOfAttributes = 8; const int numberOfAttributes = 8;
const int opcodeGetAttribute = 0x2000027; const int opcodeGetAttribute = 0x2000027;

@ -0,0 +1,140 @@
#include <boost/algorithm/string.hpp>
#include <components/esm_store/store.hpp>
#include <components/compiler/extensions.hpp>
#include <components/interpreter/interpreter.hpp>
#include <components/interpreter/runtime.hpp>
#include <components/interpreter/opcodes.hpp>
#include "../mwbase/environment.hpp"
#include "../mwworld/class.hpp"
#include "interpretercontext.hpp"
#include "ref.hpp"
#include "OgreSceneNode.h"
namespace MWScript
{
namespace Transformation
{
template<class R>
class OpSetScale : public Interpreter::Opcode0
{
public:
virtual void execute (Interpreter::Runtime& runtime)
{
MWWorld::Ptr ptr = R()(runtime);
Interpreter::Type_Float scale = runtime[0].mFloat;
runtime.pop();
MWBase::Environment::get().getWorld()->scaleObject(ptr,scale);
}
};
template<class R>
class OpGetScale : public Interpreter::Opcode0
{
public:
virtual void execute (Interpreter::Runtime& runtime)
{
MWWorld::Ptr ptr = R()(runtime);
runtime.push(ptr.getCellRef().scale);
}
};
template<class R>
class OpSetAngle : public Interpreter::Opcode0
{
public:
virtual void execute (Interpreter::Runtime& runtime)
{
MWWorld::Ptr ptr = R()(runtime);
std::string axis = runtime.getStringLiteral (runtime[0].mInteger);
runtime.pop();
Interpreter::Type_Float angle = runtime[0].mFloat;
runtime.pop();
float ax = Ogre::Radian(ptr.getRefData().getPosition().rot[0]).valueDegrees();
float ay = Ogre::Radian(ptr.getRefData().getPosition().rot[1]).valueDegrees();
float az = Ogre::Radian(ptr.getRefData().getPosition().rot[2]).valueDegrees();
if(axis == "X")
{
MWBase::Environment::get().getWorld()->rotateObject(ptr,angle,ay,az);
}
if(axis == "Y")
{
MWBase::Environment::get().getWorld()->rotateObject(ptr,ax,angle,az);
}
if(axis == "Z")
{
MWBase::Environment::get().getWorld()->rotateObject(ptr,ax,ay,angle);
}
}
};
template<class R>
class OpGetAngle : public Interpreter::Opcode0
{
public:
virtual void execute (Interpreter::Runtime& runtime)
{
MWWorld::Ptr ptr = R()(runtime);
std::string axis = runtime.getStringLiteral (runtime[0].mInteger);
runtime.pop();
if(axis == "X")
{
runtime.push(Ogre::Radian(ptr.getRefData().getPosition().rot[0]).valueDegrees());
}
if(axis == "Y")
{
runtime.push(Ogre::Radian(ptr.getRefData().getPosition().rot[1]).valueDegrees());
}
if(axis == "Z")
{
runtime.push(Ogre::Radian(ptr.getRefData().getPosition().rot[2]).valueDegrees());
}
}
};
const int opcodeSetScale = 0x2000164;
const int opcodeSetScaleExplicit = 0x2000165;
const int opcodeSetAngle = 0x2000166;
const int opcodeSetAngleExplicit = 0x2000167;
const int opcodeGetScale = 0x2000168;
const int opcodeGetScaleExplicit = 0x2000169;
const int opcodeGetAngle = 0x200016a;
const int opcodeGetAngleExplicit = 0x200016b;
void registerExtensions (Compiler::Extensions& extensions)
{
extensions.registerInstruction("setscale","f",opcodeSetScale,opcodeSetScaleExplicit);
extensions.registerFunction("getscale",'f',"",opcodeGetScale,opcodeGetScaleExplicit);
extensions.registerInstruction("setangle","Sf",opcodeSetAngle,opcodeSetAngleExplicit);
extensions.registerFunction("getangle",'f',"S",opcodeGetAngle,opcodeGetAngleExplicit);
}
void installOpcodes (Interpreter::Interpreter& interpreter)
{
interpreter.installSegment5(opcodeSetScale,new OpSetScale<ImplicitRef>);
interpreter.installSegment5(opcodeSetScaleExplicit,new OpSetScale<ExplicitRef>);
interpreter.installSegment5(opcodeSetAngle,new OpSetAngle<ImplicitRef>);
interpreter.installSegment5(opcodeSetAngleExplicit,new OpSetAngle<ExplicitRef>);
interpreter.installSegment5(opcodeGetScale,new OpGetScale<ImplicitRef>);
interpreter.installSegment5(opcodeGetScaleExplicit,new OpGetScale<ExplicitRef>);
interpreter.installSegment5(opcodeGetAngle,new OpGetAngle<ImplicitRef>);
interpreter.installSegment5(opcodeGetAngleExplicit,new OpGetAngle<ExplicitRef>);
}
}
}

@ -0,0 +1,25 @@
#ifndef GAME_SCRIPT_TRANSFORMATIONEXTENSIONS_H
#define GAME_SCRIPT_TRANSFORMATIONEXTENSIONS_H
namespace Compiler
{
class Extensions;
}
namespace Interpreter
{
class Interpreter;
}
namespace MWScript
{
/// \brief stats-related script functionality (creatures and NPCs)
namespace Transformation
{
void registerExtensions (Compiler::Extensions& extensions);
void installOpcodes (Interpreter::Interpreter& interpreter);
}
}
#endif

@ -90,7 +90,7 @@ namespace MWSound
{ {
if(devname.empty()) if(devname.empty())
throw; throw;
std::cout <<"Failed to open device \""<<devname<<"\", trying default"<< std::endl; std::cout <<"Failed to open device \""<<devname<<"\", trying default."<< std::endl << "The error given was: " << e.what() << std::endl;
mOutput->init(); mOutput->init();
Settings::Manager::setString("device", "Sound", ""); Settings::Manager::setString("device", "Sound", "");
} }

@ -91,7 +91,7 @@ MWWorld::Ptr MWWorld::Cells::getPtrAndCache (const std::string& name, Ptr::CellS
MWWorld::Cells::Cells (const ESMS::ESMStore& store, ESM::ESMReader& reader) MWWorld::Cells::Cells (const ESMS::ESMStore& store, ESM::ESMReader& reader)
: mStore (store), mReader (reader), : mStore (store), mReader (reader),
mIdCache (20, std::pair<std::string, Ptr::CellStore *> ("", 0)), /// \todo make cache size configurable mIdCache (20, std::pair<std::string, Ptr::CellStore *> ("", (Ptr::CellStore*)0)), /// \todo make cache size configurable
mIdCacheIndex (0) mIdCacheIndex (0)
{} {}

@ -194,4 +194,12 @@ namespace MWWorld
{ {
return ""; return "";
} }
void Class::adjustScale(const MWWorld::Ptr& ptr,float& scale) const
{
}
void Class::adjustRotation(const MWWorld::Ptr& ptr,float& x,float& y,float& z) const
{
}
} }

@ -187,6 +187,10 @@ namespace MWWorld
virtual std::string getEnchantment (const MWWorld::Ptr& ptr) const; virtual std::string getEnchantment (const MWWorld::Ptr& ptr) const;
///< @return the enchantment ID if the object is enchanted, otherwise an empty string ///< @return the enchantment ID if the object is enchanted, otherwise an empty string
/// (default implementation: return empty string) /// (default implementation: return empty string)
virtual void adjustScale(const MWWorld::Ptr& ptr,float& scale) const;
virtual void adjustRotation(const MWWorld::Ptr& ptr,float& x,float& y,float& z) const;
}; };
} }

@ -165,9 +165,6 @@ namespace MWWorld
for (std::vector<std::pair<std::string, Ogre::Vector3> >::const_iterator iter (actors.begin()); for (std::vector<std::pair<std::string, Ogre::Vector3> >::const_iterator iter (actors.begin());
iter!=actors.end(); ++iter) iter!=actors.end(); ++iter)
{ {
OEngine::Physic::PhysicActor* act = mEngine->getCharacter(iter->first);
//if(iter->first == "player")
// std::cout << "This is player\n";
//dirty stuff to get the camera orientation. Must be changed! //dirty stuff to get the camera orientation. Must be changed!
Ogre::SceneNode *sceneNode = mRender.getScene()->getSceneNode (iter->first); Ogre::SceneNode *sceneNode = mRender.getScene()->getSceneNode (iter->first);
@ -177,46 +174,28 @@ namespace MWWorld
Ogre::Quaternion yawQuat = yawNode->getOrientation(); Ogre::Quaternion yawQuat = yawNode->getOrientation();
Ogre::Quaternion pitchQuat = pitchNode->getOrientation(); Ogre::Quaternion pitchQuat = pitchNode->getOrientation();
// unused
//Ogre::Quaternion both = yawQuat * pitchQuat;
playerphysics->ps.viewangles.x = pitchQuat.getPitch().valueDegrees();
playerphysics->ps.viewangles.z = 0;
playerphysics->ps.viewangles.y = yawQuat.getYaw().valueDegrees() *-1 + 90;
if(mFreeFly)
{
Ogre::Vector3 dir1(iter->second.x,iter->second.z,-iter->second.y);
pm_ref.rightmove = -dir1.x; playerphysics->ps.viewangles.x = pitchQuat.getPitch().valueDegrees();
pm_ref.forwardmove = dir1.z;
pm_ref.upmove = dir1.y;
playerphysics->ps.viewangles.y = yawQuat.getYaw().valueDegrees() *-1 + 90;
//std::cout << "Current angle" << yawQuat.getYaw().valueDegrees() - 90<< "\n";
//playerphysics->ps.viewangles.x = pitchQuat.getPitch().valueDegrees();
//std::cout << "Pitch: " << yawQuat.getPitch() << "Yaw:" << yawQuat.getYaw() << "Roll: " << yawQuat.getRoll() << "\n";
dir = 0.07*(yawQuat*pitchQuat*dir1);
}
else
{
Ogre::Quaternion quat = yawNode->getOrientation(); Ogre::Quaternion quat = yawNode->getOrientation();
Ogre::Vector3 dir1(iter->second.x,iter->second.z,-iter->second.y); Ogre::Vector3 dir1(iter->second.x,iter->second.z,-iter->second.y);
pm_ref.rightmove = -dir1.x; pm_ref.rightmove = -iter->second.x;
pm_ref.forwardmove = dir1.z; pm_ref.forwardmove = -iter->second.y;
pm_ref.upmove = dir1.y; pm_ref.upmove = iter->second.z;
dir = 0.025*(quat*dir1);
} }
//set the walk direction
act->setWalkDirection(btVector3(dir.x,-dir.z,dir.y));
}
mEngine->stepSimulation(dt); mEngine->stepSimulation(dt);
} }
@ -234,10 +213,6 @@ namespace MWWorld
if(it->first == "player"){ if(it->first == "player"){
coord = playerphysics->ps.origin; coord = playerphysics->ps.origin;
//std::cout << "ZCoord: " << coord.z << "\n";
//std::cout << "Coord" << coord << "\n";
//coord = Ogre::Vector3(coord.x, coord.z, coord.y); //x, z, -y
} }
@ -262,6 +237,7 @@ namespace MWWorld
void PhysicsSystem::addObject (const std::string& handle, const std::string& mesh, void PhysicsSystem::addObject (const std::string& handle, const std::string& mesh,
const Ogre::Quaternion& rotation, float scale, const Ogre::Vector3& position) const Ogre::Quaternion& rotation, float scale, const Ogre::Vector3& position)
{ {
handleToMesh[handle] = mesh;
OEngine::Physic::RigidBody* body = mEngine->createRigidBody(mesh,handle,scale); OEngine::Physic::RigidBody* body = mEngine->createRigidBody(mesh,handle,scale);
mEngine->addRigidBody(body); mEngine->addRigidBody(body);
btTransform tr; btTransform tr;
@ -314,17 +290,27 @@ namespace MWWorld
void PhysicsSystem::rotateObject (const std::string& handle, const Ogre::Quaternion& rotation) void PhysicsSystem::rotateObject (const std::string& handle, const Ogre::Quaternion& rotation)
{ {
if (OEngine::Physic::PhysicActor* act = mEngine->getCharacter(handle)) if (OEngine::Physic::PhysicActor* act = mEngine->getCharacter(handle))
{ {
// TODO very dirty hack to avoid crash during setup -> needs cleaning up to allow
// start positions others than 0, 0, 0
act->setRotation(btQuaternion(rotation.x, rotation.y, rotation.z, rotation.w)); act->setRotation(btQuaternion(rotation.x, rotation.y, rotation.z, rotation.w));
} }
if (OEngine::Physic::RigidBody* body = mEngine->getRigidBody(handle))
{
body->getWorldTransform().setRotation(btQuaternion(rotation.x, rotation.y, rotation.z, rotation.w));
}
} }
void PhysicsSystem::scaleObject (const std::string& handle, float scale) void PhysicsSystem::scaleObject (const std::string& handle, float scale)
{ {
if(handleToMesh.find(handle) != handleToMesh.end())
{
btTransform transform = mEngine->getRigidBody(handle)->getWorldTransform();
removeObject(handle);
Ogre::Quaternion quat = Ogre::Quaternion(transform.getRotation().getW(), transform.getRotation().getX(), transform.getRotation().getY(), transform.getRotation().getZ());
Ogre::Vector3 vec = Ogre::Vector3(transform.getOrigin().getX(), transform.getOrigin().getY(), transform.getOrigin().getZ());
addObject(handle, handleToMesh[handle], quat, scale, vec);
}
} }
bool PhysicsSystem::toggleCollisionMode() bool PhysicsSystem::toggleCollisionMode()

@ -72,6 +72,7 @@ namespace MWWorld
OEngine::Physic::PhysicEngine* mEngine; OEngine::Physic::PhysicEngine* mEngine;
bool mFreeFly; bool mFreeFly;
playerMove* playerphysics; playerMove* playerphysics;
std::map<std::string, std::string> handleToMesh;
PhysicsSystem (const PhysicsSystem&); PhysicsSystem (const PhysicsSystem&);
PhysicsSystem& operator= (const PhysicsSystem&); PhysicsSystem& operator= (const PhysicsSystem&);

@ -9,6 +9,9 @@
#include "../mwmechanics/drawstate.hpp" #include "../mwmechanics/drawstate.hpp"
#undef DrawState // How did this get defined again?
// Maybe it's defined by default in every file for windows?
namespace MWBase namespace MWBase
{ {
class World; class World;

@ -597,6 +597,31 @@ namespace MWWorld
mPhysics->moveObject (ptr.getRefData().getHandle(), Ogre::Vector3 (x, y, z)); mPhysics->moveObject (ptr.getRefData().getHandle(), Ogre::Vector3 (x, y, z));
} }
void World::scaleObject (const Ptr& ptr, float scale)
{
MWWorld::Class::get(ptr).adjustScale(ptr,scale);
ptr.getCellRef().scale = scale;
//scale = scale/ptr.getRefData().getBaseNode()->getScale().x;
ptr.getRefData().getBaseNode()->setScale(scale,scale,scale);
mPhysics->scaleObject( ptr.getRefData().getHandle(), scale );
}
void World::rotateObject (const Ptr& ptr,float x,float y,float z)
{
MWWorld::Class::get(ptr).adjustRotation(ptr,x,y,z);
ptr.getRefData().getPosition().rot[0] = Ogre::Degree(x).valueRadians();
ptr.getRefData().getPosition().rot[1] = Ogre::Degree(y).valueRadians();
ptr.getRefData().getPosition().rot[2] = Ogre::Degree(z).valueRadians();
Ogre::Quaternion rotx(Ogre::Degree(x),Ogre::Vector3::UNIT_X);
Ogre::Quaternion roty(Ogre::Degree(y),Ogre::Vector3::UNIT_Y);
Ogre::Quaternion rotz(Ogre::Degree(z),Ogre::Vector3::UNIT_Z);
ptr.getRefData().getBaseNode()->setOrientation(rotz*roty*rotx);
mPhysics->rotateObject(ptr.getRefData().getHandle(),ptr.getRefData().getBaseNode()->getOrientation());
}
void World::indexToPosition (int cellX, int cellY, float &x, float &y, bool centre) const void World::indexToPosition (int cellX, int cellY, float &x, float &y, bool centre) const
{ {
const int cellSize = 8192; const int cellSize = 8192;

@ -188,7 +188,7 @@ namespace MWWorld
virtual bool toggleSky(); virtual bool toggleSky();
///< \return Resulting mode ///< \return Resulting mode
virtual void changeWeather (const std::string& region, const unsigned int id); virtual void changeWeather (const std::string& region, unsigned int id);
virtual int getCurrentWeather() const; virtual int getCurrentWeather() const;
@ -219,6 +219,10 @@ namespace MWWorld
virtual void moveObject (const Ptr& ptr, float x, float y, float z); virtual void moveObject (const Ptr& ptr, float x, float y, float z);
virtual void scaleObject (const Ptr& ptr, float scale);
virtual void rotateObject (const Ptr& ptr,float x,float y,float z);
virtual void indexToPosition (int cellX, int cellY, float &x, float &y, bool centre = false) virtual void indexToPosition (int cellX, int cellY, float &x, float &y, bool centre = false)
const; const;
///< Convert cell numbers to position. ///< Convert cell numbers to position.

@ -73,14 +73,16 @@ class DirArchive: public Ogre::FileSystemArchive
{ {
{ {
String passed = filename; String passed = filename;
if(filename.at(filename.length() - 1) == '*' || filename.at(filename.length() - 1) == '?' || filename.at(filename.length() - 1) == '<' if(filename.at(filename.length() - 2) == '>' || filename.at(filename.length() - 2) == ':')
passed = filename.substr(0, filename.length() - 6);
else if(filename.at(filename.length() - 2) == '"')
passed = filename.substr(0, filename.length() - 9);
else if(filename.at(filename.length() - 1) == '*' || filename.at(filename.length() - 1) == '?' || filename.at(filename.length() - 1) == '<'
|| filename.at(filename.length() - 1) == '"' || filename.at(filename.length() - 1) == '>' || filename.at(filename.length() - 1) == ':' || filename.at(filename.length() - 1) == '"' || filename.at(filename.length() - 1) == '>' || filename.at(filename.length() - 1) == ':'
|| filename.at(filename.length() - 1) == '|') || filename.at(filename.length() - 1) == '|')
{
passed = filename.substr(0, filename.length() - 2); passed = filename.substr(0, filename.length() - 2);
}
if(filename.at(filename.length() - 2) == '>' || filename.at(filename.length() - 2) == ':')
passed = filename.substr(0, filename.length() - 6);
copy = passed; copy = passed;
} }
@ -226,14 +228,16 @@ public:
BSAFile *narc = (BSAFile*)&arc; BSAFile *narc = (BSAFile*)&arc;
String passed = filename; String passed = filename;
if(filename.at(filename.length() - 1) == '*' || filename.at(filename.length() - 1) == '?' || filename.at(filename.length() - 1) == '<' if(filename.at(filename.length() - 2) == '>' || filename.at(filename.length() - 2) == ':')
passed = filename.substr(0, filename.length() - 6);
else if(filename.at(filename.length() - 2) == '"')
passed = filename.substr(0, filename.length() - 9);
else if(filename.at(filename.length() - 1) == '*' || filename.at(filename.length() - 1) == '?' || filename.at(filename.length() - 1) == '<'
|| filename.at(filename.length() - 1) == '"' || filename.at(filename.length() - 1) == '>' || filename.at(filename.length() - 1) == ':' || filename.at(filename.length() - 1) == '"' || filename.at(filename.length() - 1) == '>' || filename.at(filename.length() - 1) == ':'
|| filename.at(filename.length() - 1) == '|') || filename.at(filename.length() - 1) == '|')
{
passed = filename.substr(0, filename.length() - 2); passed = filename.substr(0, filename.length() - 2);
}
if(filename.at(filename.length() - 2) == '>' || filename.at(filename.length() - 2) == ':')
passed = filename.substr(0, filename.length() - 6);
// Open the file // Open the file
StreamPtr strm = narc->getFile(passed.c_str()); StreamPtr strm = narc->getFile(passed.c_str());
@ -248,14 +252,16 @@ bool exists(const String& filename) {
// Check if the file exists. // Check if the file exists.
bool cexists(const String& filename) const { bool cexists(const String& filename) const {
String passed = filename; String passed = filename;
if(filename.at(filename.length() - 1) == '*' || filename.at(filename.length() - 1) == '?' || filename.at(filename.length() - 1) == '<' if(filename.at(filename.length() - 2) == '>' || filename.at(filename.length() - 2) == ':')
passed = filename.substr(0, filename.length() - 6);
else if(filename.at(filename.length() - 2) == '"')
passed = filename.substr(0, filename.length() - 9);
else if(filename.at(filename.length() - 1) == '*' || filename.at(filename.length() - 1) == '?' || filename.at(filename.length() - 1) == '<'
|| filename.at(filename.length() - 1) == '"' || filename.at(filename.length() - 1) == '>' || filename.at(filename.length() - 1) == ':' || filename.at(filename.length() - 1) == '"' || filename.at(filename.length() - 1) == '>' || filename.at(filename.length() - 1) == ':'
|| filename.at(filename.length() - 1) == '|') || filename.at(filename.length() - 1) == '|')
{
passed = filename.substr(0, filename.length() - 2); passed = filename.substr(0, filename.length() - 2);
}
if(filename.at(filename.length() - 2) == '>' || filename.at(filename.length() - 2) == ':')
passed = filename.substr(0, filename.length() - 6);
return arc.exists(passed.c_str()); return arc.exists(passed.c_str());
} }

@ -1,4 +1,4 @@
/* /*
OpenMW - The completely unofficial reimplementation of Morrowind OpenMW - The completely unofficial reimplementation of Morrowind
Copyright (C) 2008-2010 Nicolay Korslund Copyright (C) 2008-2010 Nicolay Korslund
Email: < korslund@gmail.com > Email: < korslund@gmail.com >
@ -45,18 +45,11 @@ typedef unsigned char ubyte;
using namespace NifBullet; using namespace NifBullet;
ManualBulletShapeLoader::~ManualBulletShapeLoader() ManualBulletShapeLoader::~ManualBulletShapeLoader()
{ {
} }
Ogre::Matrix3 ManualBulletShapeLoader::getMatrix(Nif::Transformation* tr)
{
return tr->rotation;
}
Ogre::Vector3 ManualBulletShapeLoader::getVector(Nif::Transformation* tr)
{
return tr->pos;
}
btQuaternion ManualBulletShapeLoader::getbtQuat(Ogre::Matrix3 &m) btQuaternion ManualBulletShapeLoader::getbtQuat(Ogre::Matrix3 &m)
{ {
@ -109,15 +102,15 @@ void ManualBulletShapeLoader::loadResource(Ogre::Resource *resource)
bool hasCollisionNode = hasRootCollisionNode(node); bool hasCollisionNode = hasRootCollisionNode(node);
//do a first pass //do a first pass
handleNode(node,0,Ogre::Matrix3::IDENTITY,Ogre::Vector3::ZERO,1,hasCollisionNode,false,false); handleNode(node,0,NULL,hasCollisionNode,false,false);
//if collide = false, then it does a second pass which create a shape for raycasting. //if collide = false, then it does a second pass which create a shape for raycasting.
if(cShape->collide == false) if(cShape->collide == false)
{ {
handleNode(node,0,Ogre::Matrix3::IDENTITY,Ogre::Vector3::ZERO,1,hasCollisionNode,false,true); handleNode(node,0,NULL,hasCollisionNode,false,true);
} }
cShape->collide = hasCollisionNode&&cShape->collide; //cShape->collide = hasCollisionNode&&cShape->collide;
struct TriangleMeshShape : public btBvhTriangleMeshShape struct TriangleMeshShape : public btBvhTriangleMeshShape
{ {
@ -164,8 +157,9 @@ bool ManualBulletShapeLoader::hasRootCollisionNode(Nif::Node* node)
} }
void ManualBulletShapeLoader::handleNode(Nif::Node *node, int flags, void ManualBulletShapeLoader::handleNode(Nif::Node *node, int flags,
Ogre::Matrix3 parentRot,Ogre::Vector3 parentPos,float parentScale,bool hasCollisionNode,bool isCollisionNode,bool raycastingOnly) const Nif::Transformation *trafo,bool hasCollisionNode,bool isCollisionNode,bool raycastingOnly)
{ {
// Accumulate the flags from all the child nodes. This works for all // Accumulate the flags from all the child nodes. This works for all
// the flags we currently use, at least. // the flags we currently use, at least.
flags |= node->flags; flags |= node->flags;
@ -199,18 +193,26 @@ void ManualBulletShapeLoader::handleNode(Nif::Node *node, int flags,
} }
} }
//transfo of parents node + curent node
Ogre::Matrix3 finalRot;
Ogre::Vector3 finalPos;
float finalScale;
Nif::Transformation &final = node->trafo; if (trafo)
Ogre::Vector3 nodePos = getVector(&final); {
Ogre::Matrix3 nodeRot = getMatrix(&final);
finalPos = nodePos + parentPos; // Get a non-const reference to the node's data, since we're
finalRot = parentRot*nodeRot; // overwriting it. TODO: Is this necessary?
finalScale = final.scale*parentScale; Nif::Transformation &final = node->trafo;
// For both position and rotation we have that:
// final_vector = old_vector + old_rotation*new_vector*old_scale
final.pos = trafo->pos + trafo->rotation*final.pos*trafo->scale;
final.velocity = trafo->velocity + trafo->rotation*final.velocity*trafo->scale;
// Merge the rotations together
final.rotation = trafo->rotation * final.rotation;
// Scale
final.scale *= trafo->scale;
}
// For NiNodes, loop through children // For NiNodes, loop through children
@ -222,14 +224,14 @@ void ManualBulletShapeLoader::handleNode(Nif::Node *node, int flags,
{ {
if (list.has(i)) if (list.has(i))
{ {
handleNode(&list[i], flags,finalRot,finalPos,finalScale,hasCollisionNode,isCollisionNode,raycastingOnly); handleNode(&list[i], flags,&node->trafo,hasCollisionNode,isCollisionNode,raycastingOnly);
} }
} }
} }
else if (node->recType == Nif::RC_NiTriShape && (isCollisionNode || !hasCollisionNode)) else if (node->recType == Nif::RC_NiTriShape && (isCollisionNode || !hasCollisionNode))
{ {
cShape->collide = true; cShape->collide = true;
handleNiTriShape(dynamic_cast<Nif::NiTriShape*>(node), flags,finalRot,finalPos,parentScale,raycastingOnly); handleNiTriShape(dynamic_cast<Nif::NiTriShape*>(node), flags,node->trafo.rotation,node->trafo.pos,node->trafo.scale,raycastingOnly);
} }
else if(node->recType == Nif::RC_RootCollisionNode) else if(node->recType == Nif::RC_RootCollisionNode)
{ {
@ -238,7 +240,7 @@ void ManualBulletShapeLoader::handleNode(Nif::Node *node, int flags,
for (int i=0; i<n; i++) for (int i=0; i<n; i++)
{ {
if (list.has(i)) if (list.has(i))
handleNode(&list[i], flags,finalRot,finalPos,finalScale,hasCollisionNode,true,raycastingOnly); handleNode(&list[i], flags,&node->trafo, hasCollisionNode,true,raycastingOnly);
} }
} }
} }
@ -270,17 +272,19 @@ void ManualBulletShapeLoader::handleNiTriShape(Nif::NiTriShape *shape, int flags
Nif::NiTriShapeData *data = shape->data.getPtr(); Nif::NiTriShapeData *data = shape->data.getPtr();
float* vertices = (float*)&data->vertices[0]; float* vertices = &data->vertices[0];
unsigned short* triangles = (unsigned short*)&data->triangles[0]; short* triangles = &data->triangles[0];
const Ogre::Matrix3 &rot = shape->trafo.rotation;
const Ogre::Vector3 &pos = shape->trafo.pos;
float scale = shape->trafo.scale;
for(unsigned int i=0; i < data->triangles.size(); i = i+3) for(unsigned int i=0; i < data->triangles.size(); i = i+3)
{ {
Ogre::Vector3 b1(vertices[triangles[i+0]*3]*parentScale,vertices[triangles[i+0]*3+1]*parentScale,vertices[triangles[i+0]*3+2]*parentScale); Ogre::Vector3 b1(vertices[triangles[i+0]*3]*parentScale,vertices[triangles[i+0]*3+1]*parentScale,vertices[triangles[i+0]*3+2]*parentScale);
Ogre::Vector3 b2(vertices[triangles[i+1]*3]*parentScale,vertices[triangles[i+1]*3+1]*parentScale,vertices[triangles[i+1]*3+2]*parentScale); Ogre::Vector3 b2(vertices[triangles[i+1]*3]*parentScale,vertices[triangles[i+1]*3+1]*parentScale,vertices[triangles[i+1]*3+2]*parentScale);
Ogre::Vector3 b3(vertices[triangles[i+2]*3]*parentScale,vertices[triangles[i+2]*3+1]*parentScale,vertices[triangles[i+2]*3+2]*parentScale); Ogre::Vector3 b3(vertices[triangles[i+2]*3]*parentScale,vertices[triangles[i+2]*3+1]*parentScale,vertices[triangles[i+2]*3+2]*parentScale);
b1 = parentRot * b1 + parentPos; b1 = pos + rot*b1*scale;
b2 = parentRot * b2 + parentPos; b2 = pos + rot*b2*scale;
b3 = parentRot * b3 + parentPos; b3 = pos + rot*b3*scale;
mTriMesh->addTriangle(btVector3(b1.x,b1.y,b1.z),btVector3(b2.x,b2.y,b2.z),btVector3(b3.x,b3.y,b3.z)); mTriMesh->addTriangle(btVector3(b1.x,b1.y,b1.z),btVector3(b2.x,b2.y,b2.z),btVector3(b3.x,b3.y,b3.z));
} }
} }

@ -85,10 +85,6 @@ public:
void load(const std::string &name,const std::string &group); void load(const std::string &name,const std::string &group);
private: private:
Ogre::Matrix3 getMatrix(Nif::Transformation* tr);
Ogre::Vector3 getVector(Nif::Transformation* tr);
btQuaternion getbtQuat(Ogre::Matrix3 &m); btQuaternion getbtQuat(Ogre::Matrix3 &m);
btVector3 getbtVector(Ogre::Vector3 &v); btVector3 getbtVector(Ogre::Vector3 &v);
@ -97,10 +93,10 @@ private:
*Parse a node. *Parse a node.
*/ */
void handleNode(Nif::Node *node, int flags, void handleNode(Nif::Node *node, int flags,
Ogre::Matrix3 parentRot,Ogre::Vector3 parentPos,float parentScale,bool hasCollisionNode,bool isCollisionNode,bool raycastingOnly); const Nif::Transformation *trafo, bool hasCollisionNode,bool isCollisionNode,bool raycastingOnly);
/** /**
*Helpler function *Helper function
*/ */
bool hasRootCollisionNode(Nif::Node* node); bool hasRootCollisionNode(Nif::Node* node);

@ -1252,7 +1252,7 @@ void NIFLoader::loadResource(Ogre::Resource *resource)
// Look it up // Look it up
resourceName = mesh->getName(); resourceName = mesh->getName();
//std::cout << resourceName << "\n";
// Helper that computes bounding boxes for us. // Helper that computes bounding boxes for us.
BoundsFinder bounds; BoundsFinder bounds;

@ -333,11 +333,18 @@ namespace Physic
RigidBody* PhysicEngine::createRigidBody(std::string mesh,std::string name,float scale) RigidBody* PhysicEngine::createRigidBody(std::string mesh,std::string name,float scale)
{ {
char uniqueID[8];
sprintf( uniqueID, "%07.3f", scale );
std::string sid = uniqueID;
std::string outputstring = mesh + uniqueID + "\"|";
//std::cout << "The string" << outputstring << "\n";
//get the shape from the .nif //get the shape from the .nif
mShapeLoader->load(mesh,"General"); mShapeLoader->load(outputstring,"General");
BulletShapeManager::getSingletonPtr()->load(mesh,"General"); BulletShapeManager::getSingletonPtr()->load(outputstring,"General");
BulletShapePtr shape = BulletShapeManager::getSingleton().getByName(mesh,"General"); BulletShapePtr shape = BulletShapeManager::getSingleton().getByName(outputstring,"General");
shape->Shape->setLocalScaling(btVector3(scale,scale,scale)); shape->Shape->setLocalScaling( btVector3(scale,scale,scale));
//btScaledBvhTriangleMeshShape* scaled = new btScaledBvhTriangleMeshShape(dynamic_cast<btBvhTriangleMeshShape*> (shape->Shape), btVector3(scale,scale,scale));
//create the motionState //create the motionState
CMotionState* newMotionState = new CMotionState(this,name); CMotionState* newMotionState = new CMotionState(this,name);
@ -400,18 +407,32 @@ namespace Physic
if (it != RigidBodyMap.end() ) if (it != RigidBodyMap.end() )
{ {
RigidBody* body = it->second; RigidBody* body = it->second;
//btScaledBvhTriangleMeshShape* scaled = dynamic_cast<btScaledBvhTriangleMeshShape*> (body->getCollisionShape());
if(body != NULL) if(body != NULL)
{ {
delete body; delete body;
} }
/*if(scaled != NULL)
{
delete scaled;
}*/
RigidBodyMap.erase(it); RigidBodyMap.erase(it);
} }
} }
RigidBody* PhysicEngine::getRigidBody(std::string name) RigidBody* PhysicEngine::getRigidBody(std::string name)
{ {
RigidBody* body = RigidBodyMap[name]; RigidBodyContainer::iterator it = RigidBodyMap.find(name);
return body; if (it != RigidBodyMap.end() )
{
RigidBody* body = RigidBodyMap[name];
return body;
}
else
{
return 0;
}
} }
void PhysicEngine::stepSimulation(double deltaT) void PhysicEngine::stepSimulation(double deltaT)
@ -468,8 +489,16 @@ namespace Physic
PhysicActor* PhysicEngine::getCharacter(std::string name) PhysicActor* PhysicEngine::getCharacter(std::string name)
{ {
PhysicActor* act = PhysicActorMap[name]; PhysicActorContainer::iterator it = PhysicActorMap.find(name);
return act; if (it != PhysicActorMap.end() )
{
PhysicActor* act = PhysicActorMap[name];
return act;
}
else
{
return 0;
}
} }
void PhysicEngine::emptyEventLists(void) void PhysicEngine::emptyEventLists(void)

@ -7,6 +7,7 @@
#include <list> #include <list>
#include <map> #include <map>
#include "BulletShapeLoader.h" #include "BulletShapeLoader.h"
#include "BulletCollision/CollisionShapes/btScaledBvhTriangleMeshShape.h"
class btRigidBody; class btRigidBody;
class btBroadphaseInterface; class btBroadphaseInterface;

@ -229,7 +229,7 @@ bool PM_SlideMove( bool gravity )
end = pm->ps.origin + pm->ps.velocity * time_left; end = pm->ps.origin + pm->ps.velocity * time_left;
// see if we can make it there // see if we can make it there
//pm->trace ( &trace, pm->ps->origin, pm->mins, pm->maxs, end, pm->ps->clientNum, pm->tracemask); //pm->trace ( &trace, pm->ps->origin, pm->mins, pm->maxs, end, pm->ps->clientNum, pm->tracemaskg);
//tracefunc(&trace, *(const D3DXVECTOR3* const)&(pm->ps.origin), *(const D3DXVECTOR3* const)&(end), *(const D3DXVECTOR3* const)&(pm->ps.velocity), 0, pml.traceObj); //tracefunc(&trace, *(const D3DXVECTOR3* const)&(pm->ps.origin), *(const D3DXVECTOR3* const)&(end), *(const D3DXVECTOR3* const)&(pm->ps.velocity), 0, pml.traceObj);
newtrace(&trace, pm->ps.origin, end, halfExtents, Ogre::Math::DegreesToRadians (pm->ps.viewangles.y), pm->isInterior, pm->mEngine); newtrace(&trace, pm->ps.origin, end, halfExtents, Ogre::Math::DegreesToRadians (pm->ps.viewangles.y), pm->isInterior, pm->mEngine);
@ -274,7 +274,7 @@ bool PM_SlideMove( bool gravity )
{ {
// pm->ps->velocity += (trace.plane.normal + pm->ps->velocity) // pm->ps->velocity += (trace.plane.normal + pm->ps->velocity)
//VectorAdd( trace.plane.normal, pm->ps->velocity, pm->ps->velocity ); //VectorAdd( trace.plane.normal, pm->ps->velocity, pm->ps->velocity );
pm->ps.velocity = (trace.planenormal + pm->ps.velocity); pm->ps.velocity = trace.planenormal + pm->ps.velocity;
break; break;
} }
} }
@ -298,6 +298,12 @@ bool PM_SlideMove( bool gravity )
if ( into >= 0.1 ) if ( into >= 0.1 )
continue; // move doesn't interact with the plane continue; // move doesn't interact with the plane
if(planes[i].x >= .70)
{
pm->ps.velocity = Ogre::Vector3(0,0,0);
return true;
}
// see how hard we are hitting things // see how hard we are hitting things
if ( -into > pml.impactSpeed ) if ( -into > pml.impactSpeed )
pml.impactSpeed = -into; pml.impactSpeed = -into;
@ -318,6 +324,13 @@ bool PM_SlideMove( bool gravity )
if (clipVelocity.dotProduct(planes[j]) >= 0.1) if (clipVelocity.dotProduct(planes[j]) >= 0.1)
//if ( DotProduct( clipVelocity, planes[j] ) >= 0.1 ) //if ( DotProduct( clipVelocity, planes[j] ) >= 0.1 )
continue; // move doesn't interact with the plane continue; // move doesn't interact with the plane
//pm->ps.velocity = Ogre::Vector3(0,0,0);
//return true;
// try clipping the move to the plane // try clipping the move to the plane
PM_ClipVelocity( clipVelocity, planes[j], clipVelocity, OVERCLIP ); PM_ClipVelocity( clipVelocity, planes[j], clipVelocity, OVERCLIP );
@ -327,8 +340,8 @@ bool PM_SlideMove( bool gravity )
if (clipVelocity.dotProduct(planes[i]) >= 0) if (clipVelocity.dotProduct(planes[i]) >= 0)
//if ( DotProduct( clipVelocity, planes[i] ) >= 0 ) //if ( DotProduct( clipVelocity, planes[i] ) >= 0 )
continue; continue;
// slide the original velocity along the crease // slide the original velocity along the crease
//dProduct (planes[i], planes[j], dir); //dProduct (planes[i], planes[j], dir);
dir = planes[i].crossProduct(planes[j]) ; dir = planes[i].crossProduct(planes[j]) ;
@ -360,6 +373,7 @@ bool PM_SlideMove( bool gravity )
// see if there is a third plane the the new move enters // see if there is a third plane the the new move enters
for ( k = 0 ; k < numplanes ; k++ ) for ( k = 0 ; k < numplanes ; k++ )
{ {
if ( k == i || k == j ) if ( k == i || k == j )
continue; continue;
@ -513,7 +527,7 @@ int PM_StepSlideMove( bool gravity )
delta = pm->ps.origin.z - start_o.z; delta = pm->ps.origin.z - start_o.z;
if ( delta > 2 ) if ( delta > 2 )
{ {
pm->ps.counter = 10; pm->ps.counter = 5;
/* /*
if (gravity) if (gravity)
@ -844,6 +858,8 @@ static void PM_WalkMove( playerMove* const pmove )
float accelerate; float accelerate;
float vel; float vel;
//pm->ps.gravity = 4000; //pm->ps.gravity = 4000;
//std::cout << "Player is walking\n";
if ( pm->ps.waterlevel > 2 && //DotProduct( pml.forward, pml.groundTrace.plane.normal ) > 0 ) if ( pm->ps.waterlevel > 2 && //DotProduct( pml.forward, pml.groundTrace.plane.normal ) > 0 )
pml.forward.dotProduct(pml.groundTrace.planenormal) > 0.0f) pml.forward.dotProduct(pml.groundTrace.planenormal) > 0.0f)
@ -1145,6 +1161,10 @@ void PM_GroundTraceMissed()
{ {
traceResults trace; traceResults trace;
Ogre::Vector3 point; Ogre::Vector3 point;
//We should not have significant upwards velocity when in the air, unless we jumped.
//This code protects against flying into the air when moving at high speeds.
//Z velocity is set to 50, instead of 0, to help move up certain steps.
//std::cout << "Ground trace missed\n"; //std::cout << "Ground trace missed\n";
// we just transitioned into freefall // we just transitioned into freefall
//if ( pm->debugLevel ) //if ( pm->debugLevel )
@ -1407,10 +1427,13 @@ static void PM_GroundTrace( void )
// if the trace didn't hit anything, we are in free fall // if the trace didn't hit anything, we are in free fall
if ( trace.fraction == 1.0) if ( trace.fraction == 1.0)
{ {
if(pm->ps.velocity.z > 50.0f && pm->ps.bSnap && pm->ps.speed > 1000.0f)
pm->ps.velocity.z = 50.0f;
if(pm->ps.snappingImplemented){ if(pm->ps.snappingImplemented){
if(pm->ps.bSnap && pm->ps.counter <= 0) if(pm->ps.bSnap && pm->ps.counter <= 0)
PM_GroundTraceMissed(); PM_GroundTraceMissed();
} }
return; return;
@ -1457,6 +1480,7 @@ static void PM_GroundTrace( void )
// slopes that are too steep will not be considered onground // slopes that are too steep will not be considered onground
//if ( trace.plane.normal[2] < MIN_WALK_NORMAL ) //if ( trace.plane.normal[2] < MIN_WALK_NORMAL )
//std::cout << "MinWalkNormal" << trace.planenormal.z;
if (trace.planenormal.z < MIN_WALK_NORMAL) if (trace.planenormal.z < MIN_WALK_NORMAL)
{ {
//if ( pm->debugLevel ) //if ( pm->debugLevel )
@ -1569,8 +1593,11 @@ void PM_AirMove()
else else
PM_SlideMove ( qtrue ); PM_SlideMove ( qtrue );
#endif*/ #endif*/
//std::cout << "Moving in the air" << pm->ps.velocity << "\n";
/*bprintf("%i ", */PM_StepSlideMove ( true )/* )*/; /*bprintf("%i ", */PM_StepSlideMove ( true )/* )*/;
} }
static void PM_NoclipMove( void ) static void PM_NoclipMove( void )

@ -28,7 +28,7 @@ static const Ogre::Vector3 halfExtents(14.64f * 2, 14.24f * 2, 33.25f * 2);
#define MAX_CLIP_PLANES 5 #define MAX_CLIP_PLANES 5
#define OVERCLIP 1.001f #define OVERCLIP 1.001f
//#define STEPSIZE 18 // 18 is way too much //#define STEPSIZE 18 // 18 is way too much
#define STEPSIZE (18 / 2) #define STEPSIZE (9)
#ifndef M_PI #ifndef M_PI
#define M_PI 3.14159265358979323846f #define M_PI 3.14159265358979323846f
#endif #endif
@ -41,7 +41,7 @@ static const Ogre::Vector3 halfExtents(14.64f * 2, 14.24f * 2, 33.25f * 2);
#define MAX_GENTITIES (1 << GENTITYNUM_BITS) #define MAX_GENTITIES (1 << GENTITYNUM_BITS)
#define ENTITYNUM_NONE (MAX_GENTITIES - 1) #define ENTITYNUM_NONE (MAX_GENTITIES - 1)
#define ENTITYNUM_WORLD (MAX_GENTITIES - 2) #define ENTITYNUM_WORLD (MAX_GENTITIES - 2)
#define MIN_WALK_NORMAL 0.7f // can't walk on very steep slopes #define MIN_WALK_NORMAL .7f // can't walk on very steep slopes
#define JUMP_VELOCITY (270) #define JUMP_VELOCITY (270)
#define PS_PMOVEFRAMECOUNTBITS 6 #define PS_PMOVEFRAMECOUNTBITS 6
#define MINS_Z -24 #define MINS_Z -24

Loading…
Cancel
Save