1
0
Fork 1
mirror of https://github.com/TES3MP/openmw-tes3mp.git synced 2025-02-02 21:45:32 +00:00

high-level implementation, unstable

This commit is contained in:
greye 2012-07-30 23:28:14 +04:00
parent db10baafe1
commit d6150b7482
9 changed files with 135 additions and 29 deletions

View file

@ -59,6 +59,11 @@ namespace MWClass
static void registerSelf();
virtual std::string getModel(const MWWorld::Ptr &ptr) const;
virtual bool
isActor() const {
return true;
}
};
}

View file

@ -93,6 +93,11 @@ namespace MWClass
static void registerSelf();
virtual std::string getModel(const MWWorld::Ptr &ptr) const;
virtual bool
isActor() const {
return true;
}
};
}

View file

@ -132,3 +132,24 @@ void Actors::update (float duration){
for(std::map<MWWorld::Ptr, Animation*>::iterator iter = mAllActors.begin(); iter != mAllActors.end(); iter++)
iter->second->runAnimation(duration);
}
void
Actors::updateObjectCell(const MWWorld::Ptr &ptr)
{
Ogre::SceneNode *node;
MWWorld::CellStore *newCell = ptr.getCell();
if(mCellSceneNodes.find(newCell) == mCellSceneNodes.end()) {
node = mMwRoot->createChildSceneNode();
mCellSceneNodes[newCell] = node;
} else {
node = mCellSceneNodes[newCell];
}
node->addChild(ptr.getRefData().getBaseNode());
if (Animation *anim = mAllActors[ptr]) {
/// \note Update key (Ptr's are compared only with refdata so mCell
/// on key is outdated), maybe redundant
mAllActors.erase(ptr);
mAllActors[ptr] = anim;
}
}

View file

@ -45,6 +45,7 @@ namespace MWRender{
void update (float duration);
void updateObjectCell(const MWWorld::Ptr &ptr);
};
}
#endif

View file

@ -11,6 +11,7 @@
#include <components/settings/settings.hpp>
#include "../mwworld/ptr.hpp"
#include "../mwworld/class.hpp"
#include "renderconst.hpp"
@ -474,3 +475,23 @@ void Objects::rebuildStaticGeometry()
it->second->build();
}
}
void
Objects::updateObjectCell(const MWWorld::Ptr &ptr)
{
Ogre::SceneNode *node;
MWWorld::CellStore *newCell = ptr.getCell();
if(mCellSceneNodes.find(newCell) == mCellSceneNodes.end()) {
node = mMwRoot->createChildSceneNode();
mCellSceneNodes[newCell] = node;
} else {
node = mCellSceneNodes[newCell];
}
node->addChild(ptr.getRefData().getBaseNode());
/// \note Still unaware how to move aabb and static w/o full rebuild,
/// moving static objects may cause problems
insertMesh(ptr, MWWorld::Class::get(ptr).getModel(ptr));
}

View file

@ -95,6 +95,8 @@ public:
void setMwRoot(Ogre::SceneNode* root);
void rebuildStaticGeometry();
void updateObjectCell(const MWWorld::Ptr &ptr);
};
}
#endif

View file

@ -256,8 +256,25 @@ void RenderingManager::scaleObject (const MWWorld::Ptr& ptr, const Ogre::Vector3
void RenderingManager::rotateObject (const MWWorld::Ptr& ptr, const::Ogre::Quaternion& orientation){
}
void RenderingManager::moveObjectToCell (const MWWorld::Ptr& ptr, const Ogre::Vector3& position, MWWorld::Ptr::CellStore *store){
void
RenderingManager::moveObjectToCell(
const MWWorld::Ptr& ptr,
const Ogre::Vector3& pos,
MWWorld::CellStore *store)
{
Ogre::SceneNode *child =
mRendering.getScene()->getSceneNode(ptr.getRefData().getHandle());
Ogre::SceneNode *parent = child->getParentSceneNode();
parent->removeChild(child);
if (MWWorld::Class::get(ptr).isActor()) {
mActors.updateObjectCell(ptr);
} else {
mObjects.updateObjectCell(ptr);
}
child->setPosition(pos);
}
void RenderingManager::update (float duration){

View file

@ -220,6 +220,11 @@ namespace MWWorld
virtual Ptr
copyToCell(const Ptr &ptr, CellStore &cell, const ESM::Position &pos) const;
virtual bool
isActor() const {
return false;
}
};
}

View file

@ -545,47 +545,76 @@ namespace MWWorld
bool World::moveObjectImp (const Ptr& ptr, float x, float y, float z)
{
bool ret = false;
ptr.getRefData().getPosition().pos[0] = x;
ptr.getRefData().getPosition().pos[1] = y;
ptr.getRefData().getPosition().pos[2] = z;
if (ptr==mPlayer->getPlayer())
{
//std::cout << "X:" << ptr.getRefData().getPosition().pos[0] << " Z: " << ptr.getRefData().getPosition().pos[1] << "\n";
bool cellChanged = false, haveToMove = false;
Ptr::CellStore *currentCell = mWorldScene->getCurrentCell();
if (currentCell)
{
if (!(currentCell->cell->data.flags & ESM::Cell::Interior))
ESM::Position &pos = ptr.getRefData().getPosition();
pos.pos[0] = x, pos.pos[1] = y, pos.pos[2] = z;
Ogre::Vector3 vec(x, y, z);
CellStore *currCell;
// a bit ugly
if (ptr == mPlayer->getPlayer()) {
currCell = mWorldScene->getCurrentCell();
} else {
currCell = ptr.getCell();
}
if (currCell) {
if (!(currCell->cell->data.flags & ESM::Cell::Interior)) {
// exterior -> adjust loaded cells
int cellX = 0, cellY = 0;
positionToIndex (x, y, cellX, cellY);
if (currCell->cell->data.gridX != cellX ||
currCell->cell->data.gridY != cellY)
{
// exterior -> adjust loaded cells
int cellX = 0;
int cellY = 0;
if (ptr == mPlayer->getPlayer()) {
mWorldScene->changeCell(cellX, cellY, pos, false);
haveToMove = true;
} else {
CellStore *newCell =
MWBase::Environment::get().getWorld()->getExterior(cellX, cellY);
positionToIndex (x, y, cellX, cellY);
if (!mWorldScene->isCellActive(*currCell)) {
placeObject(ptr, *newCell, pos);
} else if (!mWorldScene->isCellActive(*newCell)) {
MWWorld::Class::get(ptr).copyToCell(ptr, *newCell);
mWorldScene->removeObjectFromScene(ptr);
mLocalScripts.remove(ptr);
} else {
MWWorld::Ptr copy =
MWWorld::Class::get(ptr).copyToCell(ptr, *newCell);
if (currentCell->cell->data.gridX!=cellX || currentCell->cell->data.gridY!=cellY)
{
mWorldScene->changeCell (cellX, cellY, mPlayer->getPlayer().getRefData().getPosition(), false);
ret = true;
mRendering->moveObjectToCell(copy, vec, currCell);
/// \note Maybe mechanics actors change is redundant
/// because of Ptr comparing operators
if (MWWorld::Class::get(ptr).isActor()) {
MWMechanics::MechanicsManager *mechMgr =
MWBase::Environment::get().getMechanicsManager();
mechMgr->removeActor(ptr);
mechMgr->addActor(copy);
haveToMove = true;
}
}
ptr.getRefData().setCount(0);
}
cellChanged = true;
}
}
}
/// \todo cell change for non-player ref
mRendering->moveObject (ptr, Ogre::Vector3 (x, y, z));
return ret;
if (haveToMove) {
mRendering->moveObject(ptr, vec);
mPhysics->moveObject(ptr.getRefData().getHandle(), vec);
}
return cellChanged;
}
void World::moveObject (const Ptr& ptr, float x, float y, float z)
{
moveObjectImp(ptr, x, y, z);
mPhysics->moveObject (ptr.getRefData().getHandle(), Ogre::Vector3 (x, y, z));
}
void World::scaleObject (const Ptr& ptr, float scale)