mirror of
https://github.com/OpenMW/openmw.git
synced 2025-01-30 09:15:38 +00:00
Preparing for clothes/armor
This commit is contained in:
parent
07d0203a3c
commit
57299571d5
14 changed files with 169 additions and 2502 deletions
|
@ -93,7 +93,9 @@ namespace MWClass
|
|||
|
||||
void Npc::insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const
|
||||
{
|
||||
std::cout << "Inserting NPC\n";
|
||||
renderingInterface.getActors().insertNPC(ptr);
|
||||
|
||||
}
|
||||
|
||||
void Npc::insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics, MWWorld::Environment& environment) const
|
||||
|
|
|
@ -14,6 +14,7 @@ NpcAnimation::NpcAnimation(const MWWorld::Ptr& ptr, MWWorld::Environment& _env,O
|
|||
ESMS::LiveCellRef<ESM::NPC, MWWorld::RefData> *ref =
|
||||
ptr.get<ESM::NPC>();
|
||||
|
||||
|
||||
//Part selection on last character of the file string
|
||||
// " Tri Chest
|
||||
// * Tri Tail
|
||||
|
@ -65,6 +66,7 @@ NpcAnimation::NpcAnimation(const MWWorld::Ptr& ptr, MWWorld::Environment& _env,O
|
|||
NifOgre::NIFLoader::load(smodel);
|
||||
|
||||
base = mRend.getScene()->createEntity(smodel);
|
||||
|
||||
base->setSkipAnimationStateUpdate(true); //Magical line of code, this makes the bones
|
||||
//stay in the same place when we skipanim, or open a gui window
|
||||
|
||||
|
@ -82,6 +84,7 @@ NpcAnimation::NpcAnimation(const MWWorld::Ptr& ptr, MWWorld::Environment& _env,O
|
|||
}
|
||||
textmappings = NIFLoader::getSingletonPtr()->getTextIndices(smodel);
|
||||
insert->attachObject(base);
|
||||
|
||||
|
||||
if(female)
|
||||
insert->scale(race->data.height.female, race->data.height.female, race->data.height.female);
|
||||
|
@ -124,6 +127,7 @@ NpcAnimation::NpcAnimation(const MWWorld::Ptr& ptr, MWWorld::Environment& _env,O
|
|||
insertBoundedPart("meshes\\" + upperleg->model, "Right Upper Leg");
|
||||
|
||||
}
|
||||
|
||||
if(foot){
|
||||
if(bodyRaceID.compare("b_n_khajiit_m_") == 0)
|
||||
{
|
||||
|
@ -190,28 +194,29 @@ NpcAnimation::NpcAnimation(const MWWorld::Ptr& ptr, MWWorld::Environment& _env,O
|
|||
insertBoundedPart("meshes\\" + hair->model, "Head");
|
||||
|
||||
if (chest){
|
||||
insertFreePart("meshes\\" + chest->model, ">\"", insert);
|
||||
insertFreePart("meshes\\" + chest->model, ":\"", insert);
|
||||
|
||||
|
||||
}
|
||||
if (handr){
|
||||
insertFreePart("meshes\\" + handr->model , ">?", insert);
|
||||
insertFreePart("meshes\\" + handr->model , ":?", insert);
|
||||
|
||||
}
|
||||
if (handl){
|
||||
insertFreePart("meshes\\" + handl->model, ">>", insert);
|
||||
insertFreePart("meshes\\" + handl->model, ":>", insert);
|
||||
|
||||
}
|
||||
if(tail){
|
||||
insertFreePart("meshes\\" + tail->model, ">*", insert);
|
||||
insertFreePart("meshes\\" + tail->model, ":*", insert);
|
||||
}
|
||||
if(feet){
|
||||
std::string num = getUniqueID(feet->model);
|
||||
insertFreePart("meshes\\" + feet->model,"><", insert);
|
||||
insertFreePart("meshes\\" + feet->model,">:", insert);
|
||||
insertFreePart("meshes\\" + feet->model,":<", insert);
|
||||
insertFreePart("meshes\\" + feet->model,"::", insert);
|
||||
}
|
||||
//originalpos = insert->_getWorldAABB().getCenter();
|
||||
//originalscenenode = insert->getPosition();
|
||||
|
||||
}
|
||||
|
||||
Ogre::Entity* NpcAnimation::insertBoundedPart(const std::string &mesh, std::string bonename){
|
||||
|
@ -262,7 +267,7 @@ void NpcAnimation::runAnimation(float timepassed){
|
|||
time = startTime + (time - stopTime);
|
||||
}
|
||||
|
||||
handleAnimationTransforms();
|
||||
handleAnimationTransforms();
|
||||
|
||||
std::vector<std::vector<Nif::NiTriShapeCopy>*>::iterator shapepartsiter = shapeparts.begin();
|
||||
std::vector<Ogre::Entity*>::iterator entitypartsiter = entityparts.begin();
|
||||
|
|
|
@ -5,13 +5,14 @@
|
|||
#include <OgreBillboardSet.h>
|
||||
#include <OgreHardwareOcclusionQuery.h>
|
||||
#include <OgreEntity.h>
|
||||
#include <OgreSubEntity.h>
|
||||
|
||||
using namespace MWRender;
|
||||
using namespace Ogre;
|
||||
|
||||
OcclusionQuery::OcclusionQuery(OEngine::Render::OgreRenderer* renderer, SceneNode* sunNode) :
|
||||
mSunTotalAreaQuery(0), mSunVisibleAreaQuery(0), mSingleObjectQuery(0), mActiveQuery(0),
|
||||
mDoQuery(0), mSunVisibility(0), mQuerySingleObjectStarted(false), mTestResult(false),
|
||||
mDoQuery(0), mSunVisibility(0), mQuerySingleObjectStarted(false), mTestResult(false),
|
||||
mQuerySingleObjectRequested(false), mWasVisible(false), mObjectWasVisible(false), mDoQuery2(false),
|
||||
mBBNode(0)
|
||||
{
|
||||
|
@ -84,7 +85,6 @@ OcclusionQuery::OcclusionQuery(OEngine::Render::OgreRenderer* renderer, SceneNod
|
|||
mRendering->getScene()->addRenderObjectListener(this);
|
||||
mRendering->getScene()->addRenderQueueListener(this);
|
||||
mDoQuery = true;
|
||||
mDoQuery2 = true;
|
||||
}
|
||||
|
||||
OcclusionQuery::~OcclusionQuery()
|
||||
|
@ -100,7 +100,7 @@ bool OcclusionQuery::supported()
|
|||
return mSupported;
|
||||
}
|
||||
|
||||
void OcclusionQuery::notifyRenderSingleObject(Renderable* rend, const Pass* pass, const AutoParamDataSource* source,
|
||||
void OcclusionQuery::notifyRenderSingleObject(Renderable* rend, const Pass* pass, const AutoParamDataSource* source,
|
||||
const LightList* pLightList, bool suppressRenderStateChanges)
|
||||
{
|
||||
// The following code activates and deactivates the occlusion queries
|
||||
|
@ -134,7 +134,7 @@ void OcclusionQuery::notifyRenderSingleObject(Renderable* rend, const Pass* pass
|
|||
mActiveQuery = mSingleObjectQuery;
|
||||
mObjectWasVisible = true;
|
||||
}
|
||||
|
||||
|
||||
if (mActiveQuery != NULL)
|
||||
mActiveQuery->beginOcclusionQuery();
|
||||
}
|
||||
|
@ -195,7 +195,6 @@ void OcclusionQuery::update(float duration)
|
|||
// Stop occlusion queries until we get their information
|
||||
// (may not happen on the same frame they are requested in)
|
||||
mDoQuery = false;
|
||||
mDoQuery2 = false;
|
||||
|
||||
if (!mSunTotalAreaQuery->isStillOutstanding()
|
||||
&& !mSunVisibleAreaQuery->isStillOutstanding()
|
||||
|
@ -264,3 +263,40 @@ bool OcclusionQuery::getTestResult()
|
|||
|
||||
return mTestResult;
|
||||
}
|
||||
|
||||
bool OcclusionQuery::isPotentialOccluder(Ogre::SceneNode* node)
|
||||
{
|
||||
bool result = false;
|
||||
for (unsigned int i=0; i < node->numAttachedObjects(); ++i)
|
||||
{
|
||||
MovableObject* ob = node->getAttachedObject(i);
|
||||
std::string type = ob->getMovableType();
|
||||
if (type == "Entity")
|
||||
{
|
||||
Entity* ent = static_cast<Entity*>(ob);
|
||||
for (unsigned int j=0; j < ent->getNumSubEntities(); ++j)
|
||||
{
|
||||
// if any sub entity has a material with depth write off,
|
||||
// consider the object as not an occluder
|
||||
MaterialPtr mat = ent->getSubEntity(j)->getMaterial();
|
||||
|
||||
Material::TechniqueIterator techIt = mat->getTechniqueIterator();
|
||||
while (techIt.hasMoreElements())
|
||||
{
|
||||
Technique* tech = techIt.getNext();
|
||||
Technique::PassIterator passIt = tech->getPassIterator();
|
||||
while (passIt.hasMoreElements())
|
||||
{
|
||||
Pass* pass = passIt.getNext();
|
||||
|
||||
if (pass->getDepthWriteEnabled() == false)
|
||||
return false;
|
||||
else
|
||||
result = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
|
|
@ -46,6 +46,14 @@ namespace MWRender
|
|||
*/
|
||||
bool occlusionTestPending();
|
||||
|
||||
/**
|
||||
* Checks if the objects held by this scenenode
|
||||
* can be considered as potential occluders
|
||||
* (which might not be the case when transparency is involved)
|
||||
* @param Scene node
|
||||
*/
|
||||
bool isPotentialOccluder(Ogre::SceneNode* node);
|
||||
|
||||
/**
|
||||
* @return true if the object tested in the last request was occluded
|
||||
*/
|
||||
|
|
|
@ -21,11 +21,11 @@ namespace MWWorld
|
|||
PhysicsSystem::PhysicsSystem(OEngine::Render::OgreRenderer &_rend) :
|
||||
mRender(_rend), mEngine(0), mFreeFly (true)
|
||||
{
|
||||
playerphysics = new playerMove;
|
||||
|
||||
// Create physics. shapeLoader is deleted by the physic engine
|
||||
NifBullet::ManualBulletShapeLoader* shapeLoader = new NifBullet::ManualBulletShapeLoader();
|
||||
mEngine = new OEngine::Physic::PhysicEngine(shapeLoader);
|
||||
playerphysics->mEngine = mEngine;
|
||||
|
||||
}
|
||||
|
||||
PhysicsSystem::~PhysicsSystem()
|
||||
|
@ -101,11 +101,9 @@ namespace MWWorld
|
|||
OEngine::Physic::PhysicActor* act = it->second;
|
||||
act->setWalkDirection(btVector3(0,0,0));
|
||||
}
|
||||
playerMove::playercmd& pm_ref = playerphysics->cmd;
|
||||
|
||||
pm_ref.rightmove = 0;
|
||||
pm_ref.forwardmove = 0;
|
||||
pm_ref.upmove = 0;
|
||||
|
||||
|
||||
//playerphysics->ps.move_type = PM_NOCLIP;
|
||||
for (std::vector<std::pair<std::string, Ogre::Vector3> >::const_iterator iter (actors.begin());
|
||||
iter!=actors.end(); ++iter)
|
||||
|
@ -123,9 +121,7 @@ namespace MWWorld
|
|||
Ogre::Quaternion pitchQuat = pitchNode->getOrientation();
|
||||
Ogre::Quaternion both = yawQuat * pitchQuat;
|
||||
|
||||
playerphysics->ps.viewangles.x = 0;
|
||||
playerphysics->ps.viewangles.z = 0;
|
||||
playerphysics->ps.viewangles.y = both.getYaw().valueDegrees() *-1 + 90;
|
||||
|
||||
//playerphysics->ps.viewangles.z = both.getPitch().valueDegrees();
|
||||
|
||||
|
||||
|
@ -133,8 +129,7 @@ namespace MWWorld
|
|||
{
|
||||
|
||||
Ogre::Vector3 dir1(iter->second.x,iter->second.z,-iter->second.y);
|
||||
pm_ref.rightmove = -dir1.x;
|
||||
pm_ref.forwardmove = dir1.z;
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -147,31 +142,24 @@ namespace MWWorld
|
|||
{
|
||||
Ogre::Quaternion quat = yawNode->getOrientation();
|
||||
Ogre::Vector3 dir1(iter->second.x,iter->second.z,-iter->second.y);
|
||||
pm_ref.rightmove = -dir1.x;
|
||||
pm_ref.forwardmove = dir1.z;
|
||||
|
||||
|
||||
dir = 0.025*(quat*dir1);
|
||||
}
|
||||
Pmove(playerphysics);
|
||||
|
||||
|
||||
//set the walk direction
|
||||
act->setWalkDirection(btVector3(dir.x,-dir.z,dir.y));
|
||||
}
|
||||
//mEngine->stepSimulation(duration);
|
||||
Pmove(playerphysics);
|
||||
mEngine->stepSimulation(duration);
|
||||
|
||||
std::vector< std::pair<std::string, Ogre::Vector3> > response;
|
||||
for(std::map<std::string,OEngine::Physic::PhysicActor*>::iterator it = mEngine->PhysicActorMap.begin(); it != mEngine->PhysicActorMap.end();it++)
|
||||
{
|
||||
btVector3 newPos = it->second->getPosition();
|
||||
|
||||
Ogre::Vector3 coord(newPos.x(), newPos.y(), newPos.z());
|
||||
if(it->first == "player"){
|
||||
|
||||
coord = playerphysics->ps.origin;
|
||||
//std::cout << "Coord" << coord << "\n";
|
||||
coord = Ogre::Vector3(coord.x, coord.z, coord.y); //x, z, -y
|
||||
|
||||
}
|
||||
|
||||
response.push_back(std::pair<std::string, Ogre::Vector3>(it->first, coord));
|
||||
}
|
||||
|
||||
|
|
|
@ -5,7 +5,6 @@
|
|||
#include <openengine/ogre/renderer.hpp>
|
||||
#include <openengine/bullet/physic.hpp>
|
||||
#include "ptr.hpp"
|
||||
#include <openengine/bullet/pmove.h>
|
||||
|
||||
namespace MWWorld
|
||||
{
|
||||
|
@ -54,7 +53,7 @@ namespace MWWorld
|
|||
OEngine::Render::OgreRenderer &mRender;
|
||||
OEngine::Physic::PhysicEngine* mEngine;
|
||||
bool mFreeFly;
|
||||
playerMove* playerphysics;
|
||||
|
||||
|
||||
PhysicsSystem (const PhysicsSystem&);
|
||||
PhysicsSystem& operator= (const PhysicsSystem&);
|
||||
|
|
|
@ -31,7 +31,7 @@ const float WeatherGlobals::mThunderFrequency = .4;
|
|||
const float WeatherGlobals::mThunderThreshold = 0.6;
|
||||
const float WeatherGlobals::mThunderSoundDelay = 0.25;
|
||||
|
||||
WeatherManager::WeatherManager(MWRender::RenderingManager* rendering, Environment* env) :
|
||||
WeatherManager::WeatherManager(MWRender::RenderingManager* rendering, MWWorld::Environment* env) :
|
||||
mHour(14), mCurrentWeather("clear"), mFirstUpdate(true), mWeatherUpdateTime(0),
|
||||
mThunderFlash(0), mThunderChance(0), mThunderChanceNeeded(50), mThunderSoundDelay(0)
|
||||
{
|
||||
|
@ -268,8 +268,7 @@ WeatherManager::WeatherManager(MWRender::RenderingManager* rendering, Environmen
|
|||
blight.mGlareView = 0;
|
||||
blight.mAmbientLoopSoundID = "blight";
|
||||
mWeatherSettings["blight"] = blight;
|
||||
|
||||
/*
|
||||
|
||||
Weather snow;
|
||||
snow.mCloudTexture = "tx_bm_sky_snow.dds";
|
||||
snow.mCloudsMaximumPercent = 1.0;
|
||||
|
@ -326,7 +325,6 @@ WeatherManager::WeatherManager(MWRender::RenderingManager* rendering, Environmen
|
|||
blizzard.mGlareView = 0;
|
||||
blizzard.mAmbientLoopSoundID = "BM Blizzard";
|
||||
mWeatherSettings["blizzard"] = blizzard;
|
||||
*/
|
||||
}
|
||||
|
||||
void WeatherManager::setWeather(const String& weather, bool instant)
|
||||
|
@ -508,32 +506,32 @@ void WeatherManager::update(float duration)
|
|||
float thunder = region->data.thunder/255.f;
|
||||
float ash = region->data.ash/255.f;
|
||||
float blight = region->data.blight/255.f;
|
||||
//float snow = region->data.a/255.f;
|
||||
//float blizzard = region->data.b/255.f;
|
||||
float snow = region->data.a/255.f;
|
||||
float blizzard = region->data.b/255.f;
|
||||
|
||||
// re-scale to 100 percent
|
||||
const float total = clear+cloudy+foggy+overcast+rain+thunder+ash+blight;//+snow+blizzard;
|
||||
const float total = clear+cloudy+foggy+overcast+rain+thunder+ash+blight+snow+blizzard;
|
||||
|
||||
srand(time(NULL));
|
||||
float random = ((rand()%100)/100.f) * total;
|
||||
|
||||
//if (random > snow+blight+ash+thunder+rain+overcast+foggy+cloudy+clear)
|
||||
// weather = "blizzard";
|
||||
//else if (random > blight+ash+thunder+rain+overcast+foggy+cloudy+clear)
|
||||
// weather = "snow";
|
||||
/*else*/ if (random > ash+thunder+rain+overcast+foggy+cloudy+clear)
|
||||
if (random >= snow+blight+ash+thunder+rain+overcast+foggy+cloudy+clear)
|
||||
weather = "blizzard";
|
||||
else if (random >= blight+ash+thunder+rain+overcast+foggy+cloudy+clear)
|
||||
weather = "snow";
|
||||
else if (random >= ash+thunder+rain+overcast+foggy+cloudy+clear)
|
||||
weather = "blight";
|
||||
else if (random > thunder+rain+overcast+foggy+cloudy+clear)
|
||||
else if (random >= thunder+rain+overcast+foggy+cloudy+clear)
|
||||
weather = "ashstorm";
|
||||
else if (random > rain+overcast+foggy+cloudy+clear)
|
||||
else if (random >= rain+overcast+foggy+cloudy+clear)
|
||||
weather = "thunderstorm";
|
||||
else if (random > overcast+foggy+cloudy+clear)
|
||||
else if (random >= overcast+foggy+cloudy+clear)
|
||||
weather = "rain";
|
||||
else if (random > foggy+cloudy+clear)
|
||||
else if (random >= foggy+cloudy+clear)
|
||||
weather = "overcast";
|
||||
else if (random > cloudy+clear)
|
||||
else if (random >= cloudy+clear)
|
||||
weather = "foggy";
|
||||
else if (random > clear)
|
||||
else if (random >= clear)
|
||||
weather = "cloudy";
|
||||
else
|
||||
weather = "clear";
|
||||
|
|
|
@ -543,7 +543,7 @@ namespace MWWorld
|
|||
if (ptr==mPlayer->getPlayer())
|
||||
{
|
||||
//std::cout << "X:" << ptr.getRefData().getPosition().pos[0] << " Z: " << ptr.getRefData().getPosition().pos[1] << "\n";
|
||||
|
||||
|
||||
Ptr::CellStore *currentCell = mWorldScene->getCurrentCell();
|
||||
if (currentCell)
|
||||
{
|
||||
|
@ -750,15 +750,16 @@ namespace MWWorld
|
|||
// figure out which object we want to test against
|
||||
std::vector < std::pair < float, std::string > > results = mPhysics->getFacedObjects();
|
||||
|
||||
// ignore the player
|
||||
for (std::vector < std::pair < float, std::string > >::iterator it = results.begin();
|
||||
it != results.end(); ++it)
|
||||
// ignore the player and other things we're not interested in
|
||||
std::vector < std::pair < float, std::string > >::iterator it = results.begin();
|
||||
while (it != results.end())
|
||||
{
|
||||
if ( (*it).second == mPlayer->getPlayer().getRefData().getHandle() )
|
||||
if ( getPtrViaHandle((*it).second) == mPlayer->getPlayer() )
|
||||
{
|
||||
results.erase(it);
|
||||
break;
|
||||
it = results.erase(it);
|
||||
}
|
||||
else
|
||||
++it;
|
||||
}
|
||||
|
||||
if (results.size() == 0)
|
||||
|
@ -774,6 +775,10 @@ namespace MWWorld
|
|||
btVector3 p = mPhysics->getRayPoint(results.front().first);
|
||||
Ogre::Vector3 pos(p.x(), p.z(), -p.y());
|
||||
Ogre::SceneNode* node = mFaced1.getRefData().getBaseNode();
|
||||
|
||||
//std::cout << "Num facing 1 : " << mFaced1Name << std::endl;
|
||||
//std::cout << "Type 1 " << mFaced1.getTypeName() << std::endl;
|
||||
|
||||
query->occlusionTest(pos, node);
|
||||
}
|
||||
else
|
||||
|
@ -786,8 +791,33 @@ namespace MWWorld
|
|||
|
||||
btVector3 p = mPhysics->getRayPoint(results[1].first);
|
||||
Ogre::Vector3 pos(p.x(), p.z(), -p.y());
|
||||
Ogre::SceneNode* node = mFaced2.getRefData().getBaseNode();
|
||||
query->occlusionTest(pos, node);
|
||||
Ogre::SceneNode* node1 = mFaced1.getRefData().getBaseNode();
|
||||
Ogre::SceneNode* node2 = mFaced2.getRefData().getBaseNode();
|
||||
|
||||
// no need to test if the first node is not occluder
|
||||
if (!query->isPotentialOccluder(node1) && (mFaced1.getTypeName().find("Static") == std::string::npos))
|
||||
{
|
||||
mFacedHandle = mFaced1Name;
|
||||
//std::cout << "node1 Not an occluder" << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
// no need to test if the second object is static (thus cannot be activated)
|
||||
if (mFaced2.getTypeName().find("Static") != std::string::npos)
|
||||
{
|
||||
mFacedHandle = mFaced1Name;
|
||||
return;
|
||||
}
|
||||
|
||||
// work around door problems
|
||||
if (mFaced1.getTypeName().find("Static") != std::string::npos
|
||||
&& mFaced2.getTypeName().find("Door") != std::string::npos)
|
||||
{
|
||||
mFacedHandle = mFaced2Name;
|
||||
return;
|
||||
}
|
||||
|
||||
query->occlusionTest(pos, node2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -834,6 +864,18 @@ namespace MWWorld
|
|||
return mRendering->getFader();
|
||||
}
|
||||
|
||||
Ogre::Vector2 World::getNorthVector(Ptr::CellStore* cell)
|
||||
{
|
||||
ESMS::CellRefList<ESM::Static, MWWorld::RefData> statics = cell->statics;
|
||||
ESMS::LiveCellRef<ESM::Static, MWWorld::RefData>* ref = statics.find("northmarker");
|
||||
if (!ref)
|
||||
return Vector2(0, 1);
|
||||
Ogre::SceneNode* node = ref->mData.getBaseNode();
|
||||
Vector3 dir = node->_getDerivedOrientation().yAxis();
|
||||
Vector2 d = Vector2(dir.x, dir.z);
|
||||
return d;
|
||||
}
|
||||
|
||||
void World::setWaterHeight(const float height)
|
||||
{
|
||||
mRendering->setWaterHeight(height);
|
||||
|
|
|
@ -63,13 +63,14 @@ namespace MWWorld
|
|||
enum RenderMode
|
||||
{
|
||||
Render_CollisionDebug,
|
||||
Render_Wireframe
|
||||
Render_Wireframe,
|
||||
Render_Pathgrid
|
||||
};
|
||||
|
||||
private:
|
||||
|
||||
MWRender::RenderingManager* mRendering;
|
||||
|
||||
|
||||
MWWorld::WeatherManager* mWeatherManager;
|
||||
|
||||
MWWorld::Scene *mWorldScene;
|
||||
|
@ -112,7 +113,7 @@ namespace MWWorld
|
|||
Environment& environment, const std::string& encoding);
|
||||
|
||||
~World();
|
||||
|
||||
|
||||
OEngine::Render::Fader* getFader();
|
||||
|
||||
Ptr::CellStore *getExterior (int x, int y);
|
||||
|
@ -121,7 +122,7 @@ namespace MWWorld
|
|||
|
||||
void setWaterHeight(const float height);
|
||||
void toggleWater();
|
||||
|
||||
|
||||
void adjustSky();
|
||||
|
||||
MWWorld::Player& getPlayer();
|
||||
|
@ -134,10 +135,13 @@ namespace MWWorld
|
|||
|
||||
bool hasCellChanged() const;
|
||||
///< Has the player moved to a different cell, since the last frame?
|
||||
|
||||
|
||||
bool isCellExterior() const;
|
||||
bool isCellQuasiExterior() const;
|
||||
|
||||
Ogre::Vector2 getNorthVector(Ptr::CellStore* cell);
|
||||
///< get north vector (OGRE coordinates) for given interior cell
|
||||
|
||||
Globals::Data& getGlobalVariable (const std::string& name);
|
||||
|
||||
Globals::Data getGlobalVariable (const std::string& name) const;
|
||||
|
@ -172,9 +176,9 @@ namespace MWWorld
|
|||
|
||||
bool toggleSky();
|
||||
///< \return Resulting mode
|
||||
|
||||
|
||||
void changeWeather(const std::string& region, const unsigned int id);
|
||||
|
||||
|
||||
int getCurrentWeather() const;
|
||||
|
||||
int getMasserPhase() const;
|
||||
|
|
|
@ -79,7 +79,7 @@ class DirArchive: public Ogre::FileSystemArchive
|
|||
{
|
||||
passed = filename.substr(0, filename.length() - 2);
|
||||
}
|
||||
if(filename.at(filename.length() - 2) == '>')
|
||||
if(filename.at(filename.length() - 2) == '>' || filename.at(filename.length() - 2) == ':')
|
||||
passed = filename.substr(0, filename.length() - 6);
|
||||
copy = passed;
|
||||
}
|
||||
|
@ -232,7 +232,7 @@ public:
|
|||
{
|
||||
passed = filename.substr(0, filename.length() - 2);
|
||||
}
|
||||
if(filename.at(filename.length() - 2) == '>')
|
||||
if(filename.at(filename.length() - 2) == '>' || filename.at(filename.length() - 2) == ':')
|
||||
passed = filename.substr(0, filename.length() - 6);
|
||||
// Open the file
|
||||
StreamPtr strm = narc->getFile(passed.c_str());
|
||||
|
@ -254,7 +254,7 @@ bool exists(const String& filename) {
|
|||
{
|
||||
passed = filename.substr(0, filename.length() - 2);
|
||||
}
|
||||
if(filename.at(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());
|
||||
|
|
|
@ -1296,6 +1296,7 @@ void NIFLoader::loadResource(Resource *resource)
|
|||
char suffix = name.at(name.length() - 2);
|
||||
bool addAnim = true;
|
||||
bool hasAnim = false;
|
||||
bool linkSkeleton = true;
|
||||
//bool baddin = false;
|
||||
bNiTri = true;
|
||||
if(name == "meshes\\base_anim.nif" || name == "meshes\\base_animkna.nif")
|
||||
|
@ -1326,6 +1327,17 @@ void NIFLoader::loadResource(Resource *resource)
|
|||
addAnim = false;
|
||||
|
||||
}
|
||||
else if(suffix == ':')
|
||||
{
|
||||
//baddin = true;
|
||||
linkSkeleton = false;
|
||||
bNiTri = true;
|
||||
std::string sub = name.substr(name.length() - 6, 4);
|
||||
|
||||
if(sub.compare("0000") != 0)
|
||||
addAnim = false;
|
||||
|
||||
}
|
||||
|
||||
switch(name.at(name.length() - 1))
|
||||
{
|
||||
|
@ -1464,7 +1476,7 @@ void NIFLoader::loadResource(Resource *resource)
|
|||
}
|
||||
//Don't link on npc parts to eliminate redundant skeletons
|
||||
//Will have to be changed later slightly for robes/skirts
|
||||
if(triname == "")
|
||||
if(linkSkeleton)
|
||||
mesh->_notifySkeleton(mSkel);
|
||||
}
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,197 +0,0 @@
|
|||
#ifndef OENGINE_BULLET_PMOVE_H
|
||||
#define OENGINE_BULLET_PMOVE_H
|
||||
/*
|
||||
This source file is a *modified* version of various header files from the Quake 3 Arena source code,
|
||||
which was released under the GNU GPL (v2) in 2005.
|
||||
Quake 3 Arena is copyright (C) 1999-2005 Id Software, Inc.
|
||||
*/
|
||||
|
||||
#include <Ogre.h>
|
||||
#include <OgreMath.h>
|
||||
#include <float.h>
|
||||
#include "trace.h"
|
||||
#include "physic.hpp"
|
||||
|
||||
|
||||
//#include "GameMath.h"
|
||||
//#include "GameTime.h"
|
||||
|
||||
// Forwards-declare it!
|
||||
|
||||
/*#ifndef COMPILING_PMOVE
|
||||
#include "Scene.h"
|
||||
extern SceneInstance* global_lastscene;
|
||||
#endif*/
|
||||
|
||||
static const Ogre::Vector3 halfExtents(14.64f * 2, 14.24f * 2, 33.25f * 2);
|
||||
|
||||
#define MAX_CLIP_PLANES 5
|
||||
#define OVERCLIP 1.001f
|
||||
//#define STEPSIZE 18 // 18 is way too much
|
||||
#define STEPSIZE (18 / 2)
|
||||
#ifndef M_PI
|
||||
#define M_PI 3.14159265358979323846f
|
||||
#endif
|
||||
#define YAW 0
|
||||
#define PITCH /*1*/2
|
||||
#define ROLL /*2*/1
|
||||
#define SHORT2ANGLE(x) ( (x) * (360.0f / 65536.0f) )
|
||||
#define ANGLE2SHORT(x) ( (const short)( (x) / (360.0f / 65536.0f) ) )
|
||||
#define GENTITYNUM_BITS 10 // don't need to send any more
|
||||
#define MAX_GENTITIES (1 << GENTITYNUM_BITS)
|
||||
#define ENTITYNUM_NONE (MAX_GENTITIES - 1)
|
||||
#define ENTITYNUM_WORLD (MAX_GENTITIES - 2)
|
||||
#define MIN_WALK_NORMAL 0.7f // can't walk on very steep slopes
|
||||
#define JUMP_VELOCITY (270 * 1)
|
||||
#define PS_PMOVEFRAMECOUNTBITS 6
|
||||
#define MINS_Z -24
|
||||
#define DEFAULT_VIEWHEIGHT 26
|
||||
#define CROUCH_VIEWHEIGHT 12
|
||||
#define DEAD_VIEWHEIGHT (-16)
|
||||
#define CONTENTS_SOLID 1 // an eye is never valid in a solid
|
||||
#define CONTENTS_LAVA 8
|
||||
#define CONTENTS_SLIME 16
|
||||
#define CONTENTS_WATER 32
|
||||
#define CONTENTS_FOG 64
|
||||
static const float pm_accelerate = 10.0f;
|
||||
static const float pm_stopspeed = 100.0f;
|
||||
static const float pm_friction = 6.0f;
|
||||
static const float pm_flightfriction = 3.0f;
|
||||
static const float pm_waterfriction = 1.0f;
|
||||
static const float pm_airaccelerate = 1.0f;
|
||||
static const float pm_swimScale = 0.50f;
|
||||
static const float pm_duckScale = 0.25f;
|
||||
static const float pm_flyaccelerate = 8.0f;
|
||||
static const float pm_wateraccelerate = 4.0f;
|
||||
|
||||
enum pmtype_t : unsigned char
|
||||
{
|
||||
PM_NORMAL, // can accelerate and turn
|
||||
PM_NOCLIP, // noclip movement
|
||||
PM_SPECTATOR, // still run into walls
|
||||
PM_DEAD, // no acceleration or turning, but free falling
|
||||
PM_FREEZE, // stuck in place with no control
|
||||
PM_INTERMISSION, // no movement or status bar
|
||||
PM_SPINTERMISSION // no movement or status bar
|
||||
};
|
||||
|
||||
enum waterlevel_t : unsigned char
|
||||
{
|
||||
WL_DRYLAND = 0,
|
||||
WL_ANKLE,
|
||||
WL_WAIST,
|
||||
WL_UNDERWATER
|
||||
};
|
||||
|
||||
|
||||
//#include "bprintf.h"
|
||||
|
||||
struct playerMove
|
||||
{
|
||||
struct playerStruct
|
||||
{
|
||||
playerStruct() : gravity(50.0f), speed(320.0f), pmove_framecount(20), groundEntityNum(ENTITYNUM_NONE), commandTime(40), move_type(PM_NORMAL), pm_time(0)
|
||||
{
|
||||
origin = Ogre::Vector3(733.164f,1000.0f, 839.432f);
|
||||
velocity = Ogre::Vector3(0.0f, 0.0f, 0.0f);
|
||||
|
||||
viewangles = Ogre::Vector3(0.0f, 0.0f, 0.0f);
|
||||
|
||||
delta_angles[0] = delta_angles[1] = delta_angles[2] = 0;
|
||||
|
||||
lastframe_origin.x = lastframe_origin.y = lastframe_origin.z = 0;
|
||||
lerp_multiplier.x = lerp_multiplier.y = lerp_multiplier.z = 0;
|
||||
}
|
||||
|
||||
inline void SpeedUp(void)
|
||||
{
|
||||
printf("speed up to: %f\n", speed);
|
||||
speed *= 1.25f;
|
||||
}
|
||||
|
||||
inline void SpeedDown(void)
|
||||
{
|
||||
printf("speed down to %f\n", speed);
|
||||
speed /= 1.25f;
|
||||
}
|
||||
|
||||
Ogre::Vector3 velocity;
|
||||
Ogre::Vector3 origin;
|
||||
float gravity; // default = 800
|
||||
float speed; // default = 320
|
||||
|
||||
int commandTime; // the time at which this command was issued (in milliseconds)
|
||||
|
||||
int pm_time;
|
||||
|
||||
Ogre::Vector3 viewangles;
|
||||
|
||||
int groundEntityNum;
|
||||
|
||||
int pmove_framecount;
|
||||
|
||||
int watertype;
|
||||
waterlevel_t waterlevel;
|
||||
|
||||
signed short delta_angles[3];
|
||||
|
||||
pmtype_t move_type;
|
||||
|
||||
float last_compute_time;
|
||||
Ogre::Vector3 lastframe_origin;
|
||||
Ogre::Vector3 lerp_multiplier;
|
||||
} ps;
|
||||
|
||||
struct playercmd
|
||||
{
|
||||
enum CMDstateChange
|
||||
{
|
||||
NO_CHANGE,
|
||||
KEYDOWN,
|
||||
KEYUP
|
||||
};
|
||||
|
||||
playercmd() : forwardmove(0), rightmove(0), upmove(0), serverTime(50), ducking(false),
|
||||
activating(false), lastActivatingState(false), procActivating(NO_CHANGE),
|
||||
dropping(false), lastDroppingState(false), procDropping(NO_CHANGE)
|
||||
{
|
||||
angles[0] = angles[1] = angles[2] = 0;
|
||||
}
|
||||
|
||||
int serverTime;
|
||||
|
||||
short angles[3];
|
||||
|
||||
signed char forwardmove;
|
||||
signed char rightmove;
|
||||
signed char upmove;
|
||||
|
||||
bool ducking;
|
||||
bool activating; // if the user is holding down the activate button
|
||||
bool dropping; // if the user is dropping an item
|
||||
|
||||
bool lastActivatingState;
|
||||
bool lastDroppingState;
|
||||
|
||||
CMDstateChange procActivating;
|
||||
CMDstateChange procDropping;
|
||||
} cmd;
|
||||
|
||||
playerMove() : msec(50), pmove_fixed(false), pmove_msec(50), waterHeight(0), isInterior(true), hasWater(false)
|
||||
{
|
||||
}
|
||||
|
||||
int msec;
|
||||
int pmove_msec;
|
||||
bool pmove_fixed;
|
||||
int waterHeight;
|
||||
bool hasWater;
|
||||
bool isInterior;
|
||||
//Object* traceObj;
|
||||
OEngine::Physic::PhysicEngine* mEngine;
|
||||
};
|
||||
|
||||
void Pmove (playerMove* const pmove);
|
||||
void Ext_UpdateViewAngles(playerMove* const pm);
|
||||
void AngleVectors( const Ogre::Vector3& angles, Ogre::Vector3* const forward, Ogre::Vector3* const right, Ogre::Vector3* const up) ;
|
||||
#endif
|
|
@ -1,188 +0,0 @@
|
|||
|
||||
#include "trace.h"
|
||||
|
||||
|
||||
|
||||
#include <map>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void newtrace(traceResults* const results, const Ogre::Vector3& start, const Ogre::Vector3& end, const Ogre::Vector3& BBHalfExtents, const float rotation, bool isInterior, OEngine::Physic::PhysicEngine* enginePass) //Traceobj was a Aedra Object
|
||||
{
|
||||
|
||||
//if (!traceobj)
|
||||
// return;
|
||||
|
||||
//if (!traceobj->incellptr)
|
||||
// return;
|
||||
|
||||
const Ogre::Vector3 rayDir = end - start;
|
||||
|
||||
// Nudge starting point backwards
|
||||
//const Position3D nudgestart = start + (rayDir * -0.1f); // by 10% (isn't that too much?)
|
||||
//const Position3D nudgestart = start;
|
||||
|
||||
NewPhysTraceResults out;
|
||||
//std::cout << "Starting trace\n";
|
||||
Ogre::Vector3 startReplace = Ogre::Vector3(650,950, 45);
|
||||
Ogre::Vector3 endReplace = startReplace;
|
||||
endReplace.y -= .25;
|
||||
|
||||
const bool hasHit = NewPhysicsTrace<collisionWorldTrace>(&out, start, end, BBHalfExtents, Ogre::Vector3(0.0f, rotation, 0.0f), isInterior, enginePass);
|
||||
if(hasHit)
|
||||
std::cout << "Has hit\n";
|
||||
if (out.fraction < 0.001f)
|
||||
results->startsolid = true;
|
||||
else
|
||||
results->startsolid = false;
|
||||
|
||||
|
||||
//results->allsolid = out.startSolid;
|
||||
|
||||
// If outside and underground, we're solid
|
||||
/*if (isInterior)
|
||||
{
|
||||
const Ogre::Vector3 height = GetGroundPosition(start, CellCoords(traceCell->data->gridX, traceCell->data->gridY) );
|
||||
if (start.yPos - height.yPos < (-2.0f * BBHalfExtents.yPos) )
|
||||
{
|
||||
results->allsolid = true;
|
||||
}
|
||||
else
|
||||
results->allsolid = false;
|
||||
}*/
|
||||
|
||||
// If inside and out of the tree, we're solid
|
||||
//else
|
||||
//{
|
||||
results->allsolid = out.startSolid;
|
||||
//std::cout << "allsolid" << results->allsolid << "\n";
|
||||
//}
|
||||
|
||||
if (!hasHit)
|
||||
{
|
||||
results->endpos = end;
|
||||
results->planenormal = Ogre::Vector3(0.0f, 1.0f, 0.0f);
|
||||
results->entityNum = ENTITYNUM_NONE;
|
||||
results->fraction = 1.0f;
|
||||
}
|
||||
else
|
||||
{
|
||||
results->fraction = out.fraction;
|
||||
results->planenormal = out.hitNormal;
|
||||
results->endpos = rayDir * results->fraction + start;
|
||||
results->entityNum = ENTITYNUM_WORLD;
|
||||
/*bprintf("Start: (%f, %f, %f) End: (%f, %f, %f) TraceDir: (%f, %f, %f) HitNormal: (%f, %f, %f) Fraction: %f Hitpos: (%f, %f, %f) CompensatedHitpos: (%f, %f, %f)\n",
|
||||
start.xPos, start.yPos, start.zPos,
|
||||
end.xPos, end.yPos, end.zPos,
|
||||
rayDir.xPos, rayDir.yPos, rayDir.zPos,
|
||||
results->planenormal.xPos, results->planenormal.yPos, results->planenormal.zPos, results->fraction,
|
||||
out.endPos.xPos, out.endPos.yPos, out.endPos.zPos,
|
||||
results->endpos.xPos, results->endpos.yPos, results->endpos.zPos);*/
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
template <const traceWorldType traceType>
|
||||
const bool NewPhysicsTrace(NewPhysTraceResults* const out, const Ogre::Vector3& start, const Ogre::Vector3& end,
|
||||
const Ogre::Vector3& BBHalfExtents, const Ogre::Vector3& rotation, bool isInterior, OEngine::Physic::PhysicEngine* enginePass)
|
||||
{
|
||||
//if (!traceobj->incellptr)
|
||||
// return false;
|
||||
//if(enginePass->dynamicsWorld->getCollisionObjectArray().at(60)->getCollisionShape()->isConvex())
|
||||
// std::cout << "It's convex\n";
|
||||
|
||||
|
||||
|
||||
const btVector3 btstart(start.x, start.y, start.z);
|
||||
const btVector3 btend(end.x, end.y, end.z);
|
||||
const btQuaternion btrot(rotation.y, rotation.x, rotation.z);
|
||||
|
||||
const btBoxShape newshape(btVector3(BBHalfExtents.x, BBHalfExtents.y, BBHalfExtents.z));
|
||||
const btTransform from(btrot, btstart);
|
||||
const btTransform to(btrot, btend);
|
||||
float x = from.getOrigin().getX();
|
||||
float y = from.getOrigin().getY();
|
||||
float z = from.getOrigin().getZ();
|
||||
float x2 = to.getOrigin().getX();
|
||||
float y2 = to.getOrigin().getY();
|
||||
float z2 = to.getOrigin().getZ();
|
||||
|
||||
std::cout << "BtFrom: " << x << "," << y << "," << z << "\n";
|
||||
std::cout << "BtTo: " << x2 << "," << y2 << "," << z2 << "\n";
|
||||
//std::cout << "BtTo: " << to.getOrigin().getX() << "," << to.getOrigin().getY() << "," << to.getOrigin().getZ() << "\n";
|
||||
|
||||
|
||||
btCollisionWorld::ClosestConvexResultCallback
|
||||
newTraceCallback(btstart, btend);
|
||||
|
||||
newTraceCallback.m_collisionFilterMask = (traceType == collisionWorldTrace) ? Only_Collision : Only_Pickup;
|
||||
|
||||
|
||||
enginePass->dynamicsWorld->convexSweepTest(&newshape, from, to, newTraceCallback);
|
||||
//newTraceCallback.
|
||||
|
||||
|
||||
//std::cout << "NUM: " << enginePass->dynamicsWorld->getNumCollisionObjects() << "\n";
|
||||
|
||||
// Copy the hit data over to our trace results struct:
|
||||
out->fraction = newTraceCallback.m_closestHitFraction;
|
||||
|
||||
Ogre::Vector3& outhitnormal = out->hitNormal;
|
||||
const btVector3& tracehitnormal = newTraceCallback.m_hitNormalWorld;
|
||||
|
||||
outhitnormal.x = tracehitnormal.x();
|
||||
outhitnormal.y = tracehitnormal.y();
|
||||
outhitnormal.z = tracehitnormal.z();
|
||||
|
||||
Ogre::Vector3& outhitpos = out->endPos;
|
||||
const btVector3& tracehitpos = newTraceCallback.m_hitPointWorld;
|
||||
|
||||
outhitpos.x = tracehitpos.x();
|
||||
outhitpos.y = tracehitpos.y();
|
||||
outhitpos.z= tracehitpos.z();
|
||||
|
||||
// StartSolid test:
|
||||
{
|
||||
out->startSolid = false;
|
||||
//btCollisionObject collision;
|
||||
//collision.setCollisionShape(const_cast<btBoxShape* const>(&newshape) );
|
||||
|
||||
//CustomContactCallback crb;
|
||||
|
||||
//world.world->contactTest(&collision, crb);
|
||||
//out->startSolid = crb.hit;
|
||||
|
||||
// If outside and underground, we're solid
|
||||
if (!isInterior) //Check if we are interior
|
||||
{
|
||||
}
|
||||
|
||||
// If inside and out of the tree, we're solid
|
||||
else
|
||||
{
|
||||
btVector3 aabbMin, aabbMax;
|
||||
enginePass->broadphase->getBroadphaseAabb(aabbMin, aabbMax);
|
||||
//std::cout << "AABBMIN" << aabbMin.getX() <<"," <<aabbMin.getY() << "," << aabbMin.getZ() << "\n";
|
||||
//std::cout << "AABBMAX" << aabbMax.getX() <<"," <<aabbMax.getY() << "," << aabbMax.getZ() << "\n";
|
||||
//std::cout << "AABBMAX" << aabbMax << "\n";
|
||||
if (!TestPointAgainstAabb2(aabbMin, aabbMax, *(const btVector3* const)&(start) ) )
|
||||
{
|
||||
//We're solid
|
||||
out->startSolid = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const bool hasHit = newTraceCallback.hasHit();
|
||||
|
||||
if(hasHit)
|
||||
std::cout << "HIT\n";
|
||||
|
||||
|
||||
return hasHit;
|
||||
}
|
Loading…
Reference in a new issue