mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-02-02 18:45:32 +00:00
high-level implementation, unstable
This commit is contained in:
parent
db10baafe1
commit
d6150b7482
9 changed files with 135 additions and 29 deletions
|
@ -59,6 +59,11 @@ namespace MWClass
|
|||
static void registerSelf();
|
||||
|
||||
virtual std::string getModel(const MWWorld::Ptr &ptr) const;
|
||||
|
||||
virtual bool
|
||||
isActor() const {
|
||||
return true;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -93,6 +93,11 @@ namespace MWClass
|
|||
static void registerSelf();
|
||||
|
||||
virtual std::string getModel(const MWWorld::Ptr &ptr) const;
|
||||
|
||||
virtual bool
|
||||
isActor() const {
|
||||
return true;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -45,6 +45,7 @@ namespace MWRender{
|
|||
|
||||
void update (float duration);
|
||||
|
||||
void updateObjectCell(const MWWorld::Ptr &ptr);
|
||||
};
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
||||
|
|
|
@ -95,6 +95,8 @@ public:
|
|||
void setMwRoot(Ogre::SceneNode* root);
|
||||
|
||||
void rebuildStaticGeometry();
|
||||
|
||||
void updateObjectCell(const MWWorld::Ptr &ptr);
|
||||
};
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -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){
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in a new issue