mirror of
https://github.com/OpenMW/openmw.git
synced 2025-02-22 20:09:43 +00:00
Merge remote-tracking branch 'origin/master'
This commit is contained in:
commit
fa9ebc50a2
12 changed files with 140 additions and 46 deletions
|
@ -1743,6 +1743,7 @@ namespace MWGui
|
|||
MyGUI::IntSize screenSize = MyGUI::RenderManager::getInstance().getViewSize();
|
||||
sizeVideo(screenSize.width, screenSize.height);
|
||||
|
||||
MyGUI::Widget* oldKeyFocus = MyGUI::InputManager::getInstance().getKeyFocusWidget();
|
||||
setKeyFocusWidget(mVideoWidget);
|
||||
|
||||
mVideoBackground->setVisible(true);
|
||||
|
@ -1770,6 +1771,8 @@ namespace MWGui
|
|||
|
||||
MWBase::Environment::get().getSoundManager()->resumeSounds();
|
||||
|
||||
setKeyFocusWidget(oldKeyFocus);
|
||||
|
||||
setCursorVisible(cursorWasVisible);
|
||||
|
||||
// Restore normal rendering
|
||||
|
|
|
@ -601,9 +601,9 @@ namespace MWScript
|
|||
return mTargetId;
|
||||
}
|
||||
|
||||
void InterpreterContext::updatePtr(const MWWorld::Ptr& updated)
|
||||
void InterpreterContext::updatePtr(const MWWorld::Ptr& base, const MWWorld::Ptr& updated)
|
||||
{
|
||||
if (!mReference.isEmpty())
|
||||
if (!mReference.isEmpty() && base == mReference)
|
||||
mReference = updated;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -167,7 +167,7 @@ namespace MWScript
|
|||
MWWorld::Ptr getReference(bool required=true);
|
||||
///< Reference, that the script is running from (can be empty)
|
||||
|
||||
void updatePtr(const MWWorld::Ptr& updated);
|
||||
void updatePtr(const MWWorld::Ptr& base, const MWWorld::Ptr& updated);
|
||||
///< Update the Ptr stored in mReference, if there is one stored there. Should be called after the reference has been moved to a new cell.
|
||||
|
||||
virtual std::string getTargetId() const;
|
||||
|
|
|
@ -186,7 +186,7 @@ namespace MWScript
|
|||
runtime.push(ptr.getRefData().getPosition().pos[2]);
|
||||
}
|
||||
else
|
||||
throw std::runtime_error ("invalid axis: " + axis);
|
||||
throw std::runtime_error ("invalid axis: " + axis);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -232,7 +232,7 @@ namespace MWScript
|
|||
else
|
||||
throw std::runtime_error ("invalid axis: " + axis);
|
||||
|
||||
dynamic_cast<MWScript::InterpreterContext&>(runtime.getContext()).updatePtr(updated);
|
||||
dynamic_cast<MWScript::InterpreterContext&>(runtime.getContext()).updatePtr(ptr,updated);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -300,7 +300,7 @@ namespace MWScript
|
|||
}
|
||||
catch(std::exception&)
|
||||
{
|
||||
const ESM::Cell* cell = MWBase::Environment::get().getWorld()->getExterior(cellID);
|
||||
const ESM::Cell* cell = MWBase::Environment::get().getWorld()->getExterior(cellID);
|
||||
int cx,cy;
|
||||
MWBase::Environment::get().getWorld()->positionToIndex(x,y,cx,cy);
|
||||
store = MWBase::Environment::get().getWorld()->getExterior(cx,cy);
|
||||
|
@ -312,9 +312,9 @@ namespace MWScript
|
|||
}
|
||||
if(store)
|
||||
{
|
||||
MWBase::Environment::get().getWorld()->moveObject(ptr,store,x,y,z);
|
||||
ptr = MWWorld::Ptr(ptr.getBase(), store);
|
||||
dynamic_cast<MWScript::InterpreterContext&>(runtime.getContext()).updatePtr(ptr);
|
||||
MWWorld::Ptr base = ptr;
|
||||
ptr = MWBase::Environment::get().getWorld()->moveObject(ptr,store,x,y,z);
|
||||
dynamic_cast<MWScript::InterpreterContext&>(runtime.getContext()).updatePtr(base,ptr);
|
||||
|
||||
float ax = osg::RadiansToDegrees(ptr.getRefData().getPosition().rot[0]);
|
||||
float ay = osg::RadiansToDegrees(ptr.getRefData().getPosition().rot[1]);
|
||||
|
@ -360,17 +360,17 @@ namespace MWScript
|
|||
|
||||
// another morrowind oddity: player will be moved to the exterior cell at this location,
|
||||
// non-player actors will move within the cell they are in.
|
||||
MWWorld::Ptr base = ptr;
|
||||
if (ptr == MWMechanics::getPlayer())
|
||||
{
|
||||
MWWorld::CellStore* cell = MWBase::Environment::get().getWorld()->getExterior(cx,cy);
|
||||
MWBase::Environment::get().getWorld()->moveObject(ptr,cell,x,y,z);
|
||||
ptr = MWWorld::Ptr(ptr.getBase(), cell);
|
||||
ptr = MWBase::Environment::get().getWorld()->moveObject(ptr,cell,x,y,z);
|
||||
}
|
||||
else
|
||||
{
|
||||
ptr = MWBase::Environment::get().getWorld()->moveObject(ptr, x, y, z);
|
||||
}
|
||||
dynamic_cast<MWScript::InterpreterContext&>(runtime.getContext()).updatePtr(ptr);
|
||||
dynamic_cast<MWScript::InterpreterContext&>(runtime.getContext()).updatePtr(base,ptr);
|
||||
|
||||
float ax = osg::RadiansToDegrees(ptr.getRefData().getPosition().rot[0]);
|
||||
float ay = osg::RadiansToDegrees(ptr.getRefData().getPosition().rot[1]);
|
||||
|
@ -627,7 +627,7 @@ namespace MWScript
|
|||
|
||||
MWBase::Environment::get().getWorld()->rotateObject(ptr, xr, yr, zr);
|
||||
|
||||
dynamic_cast<MWScript::InterpreterContext&>(runtime.getContext()).updatePtr(
|
||||
dynamic_cast<MWScript::InterpreterContext&>(runtime.getContext()).updatePtr(ptr,
|
||||
MWBase::Environment::get().getWorld()->moveObject(ptr, ptr.getCellRef().getPosition().pos[0],
|
||||
ptr.getCellRef().getPosition().pos[1], ptr.getCellRef().getPosition().pos[2]));
|
||||
|
||||
|
@ -745,8 +745,8 @@ namespace MWScript
|
|||
interpreter.installSegment5(Compiler::Transformation::opcodePositionExplicit,new OpPosition<ExplicitRef>);
|
||||
interpreter.installSegment5(Compiler::Transformation::opcodePositionCell,new OpPositionCell<ImplicitRef>);
|
||||
interpreter.installSegment5(Compiler::Transformation::opcodePositionCellExplicit,new OpPositionCell<ExplicitRef>);
|
||||
interpreter.installSegment5(Compiler::Transformation::opcodePlaceItemCell,new OpPlaceItemCell<ImplicitRef>);
|
||||
interpreter.installSegment5(Compiler::Transformation::opcodePlaceItem,new OpPlaceItem<ImplicitRef>);
|
||||
interpreter.installSegment5(Compiler::Transformation::opcodePlaceItemCell,new OpPlaceItemCell<ImplicitRef>);
|
||||
interpreter.installSegment5(Compiler::Transformation::opcodePlaceItem,new OpPlaceItem<ImplicitRef>);
|
||||
interpreter.installSegment5(Compiler::Transformation::opcodePlaceAtPc,new OpPlaceAt<ImplicitRef, true>);
|
||||
interpreter.installSegment5(Compiler::Transformation::opcodePlaceAtMe,new OpPlaceAt<ImplicitRef, false>);
|
||||
interpreter.installSegment5(Compiler::Transformation::opcodePlaceAtMeExplicit,new OpPlaceAt<ExplicitRef, false>);
|
||||
|
|
|
@ -1870,7 +1870,7 @@ namespace MWWorld
|
|||
orig.z() += 20;
|
||||
osg::Vec3f dir (0, 0, -1);
|
||||
|
||||
float len = 100.0;
|
||||
float len = 1000000.0;
|
||||
|
||||
MWRender::RenderingManager::RayResult result = mRendering->castRay(orig, orig+dir*len, true, true);
|
||||
if (result.mHit)
|
||||
|
|
|
@ -5,29 +5,19 @@
|
|||
namespace Nif
|
||||
{
|
||||
|
||||
void NiLight::SLight::read(NIFStream *nif)
|
||||
void NiLight::read(NIFStream *nif)
|
||||
{
|
||||
NiDynamicEffect::read(nif);
|
||||
|
||||
dimmer = nif->getFloat();
|
||||
ambient = nif->getVector3();
|
||||
diffuse = nif->getVector3();
|
||||
specular = nif->getVector3();
|
||||
}
|
||||
|
||||
void NiLight::read(NIFStream *nif)
|
||||
{
|
||||
Effect::read(nif);
|
||||
|
||||
nif->getInt(); // 1
|
||||
nif->getInt(); // 1?
|
||||
light.read(nif);
|
||||
}
|
||||
|
||||
void NiTextureEffect::read(NIFStream *nif)
|
||||
{
|
||||
Effect::read(nif);
|
||||
|
||||
int tmp = nif->getInt();
|
||||
if(tmp) nif->getInt(); // always 1?
|
||||
NiDynamicEffect::read(nif);
|
||||
|
||||
/*
|
||||
3 x Vector4 = [1,0,0,0]
|
||||
|
@ -52,10 +42,25 @@ void NiTextureEffect::read(NIFStream *nif)
|
|||
|
||||
void NiTextureEffect::post(NIFFile *nif)
|
||||
{
|
||||
Effect::post(nif);
|
||||
NiDynamicEffect::post(nif);
|
||||
texture.post(nif);
|
||||
}
|
||||
|
||||
void NiPointLight::read(NIFStream *nif)
|
||||
{
|
||||
NiLight::read(nif);
|
||||
|
||||
constantAttenuation = nif->getFloat();
|
||||
linearAttenuation = nif->getFloat();
|
||||
quadraticAttenuation = nif->getFloat();
|
||||
}
|
||||
|
||||
void NiSpotLight::read(NIFStream *nif)
|
||||
{
|
||||
NiPointLight::read(nif);
|
||||
|
||||
cutoff = nif->getFloat();
|
||||
exponent = nif->getFloat();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -29,27 +29,45 @@
|
|||
namespace Nif
|
||||
{
|
||||
|
||||
typedef Node Effect;
|
||||
|
||||
// Used for NiAmbientLight and NiDirectionalLight. Might also work for
|
||||
// NiPointLight and NiSpotLight?
|
||||
struct NiLight : Effect
|
||||
struct NiDynamicEffect : public Node
|
||||
{
|
||||
struct SLight
|
||||
void read(NIFStream *nif)
|
||||
{
|
||||
float dimmer;
|
||||
osg::Vec3f ambient;
|
||||
osg::Vec3f diffuse;
|
||||
osg::Vec3f specular;
|
||||
Node::read(nif);
|
||||
unsigned int numAffectedNodes = nif->getUInt();
|
||||
for (unsigned int i=0; i<numAffectedNodes; ++i)
|
||||
nif->getUInt(); // ref to another Node
|
||||
}
|
||||
};
|
||||
|
||||
void read(NIFStream *nif);
|
||||
};
|
||||
SLight light;
|
||||
// Used as base for NiAmbientLight, NiDirectionalLight, NiPointLight and NiSpotLight.
|
||||
struct NiLight : NiDynamicEffect
|
||||
{
|
||||
float dimmer;
|
||||
osg::Vec3f ambient;
|
||||
osg::Vec3f diffuse;
|
||||
osg::Vec3f specular;
|
||||
|
||||
void read(NIFStream *nif);
|
||||
};
|
||||
|
||||
struct NiTextureEffect : Effect
|
||||
struct NiPointLight : public NiLight
|
||||
{
|
||||
float constantAttenuation;
|
||||
float linearAttenuation;
|
||||
float quadraticAttenuation;
|
||||
|
||||
void read(NIFStream *nif);
|
||||
};
|
||||
|
||||
struct NiSpotLight : public NiPointLight
|
||||
{
|
||||
float cutoff;
|
||||
float exponent;
|
||||
void read(NIFStream *nif);
|
||||
};
|
||||
|
||||
struct NiTextureEffect : NiDynamicEffect
|
||||
{
|
||||
NiSourceTexturePtr texture;
|
||||
|
||||
|
|
|
@ -48,6 +48,8 @@ static std::map<std::string,RecordFactoryEntry> makeFactory()
|
|||
{
|
||||
std::map<std::string,RecordFactoryEntry> newFactory;
|
||||
newFactory.insert(makeEntry("NiNode", &construct <NiNode> , RC_NiNode ));
|
||||
newFactory.insert(makeEntry("NiSwitchNode", &construct <NiSwitchNode> , RC_NiSwitchNode ));
|
||||
newFactory.insert(makeEntry("NiLODNode", &construct <NiLODNode> , RC_NiLODNode ));
|
||||
newFactory.insert(makeEntry("AvoidNode", &construct <NiNode> , RC_AvoidNode ));
|
||||
newFactory.insert(makeEntry("NiBSParticleNode", &construct <NiNode> , RC_NiBSParticleNode ));
|
||||
newFactory.insert(makeEntry("NiBSAnimationNode", &construct <NiNode> , RC_NiBSAnimationNode ));
|
||||
|
@ -80,6 +82,8 @@ static std::map<std::string,RecordFactoryEntry> makeFactory()
|
|||
newFactory.insert(makeEntry("NiFlipController", &construct <NiFlipController> , RC_NiFlipController ));
|
||||
newFactory.insert(makeEntry("NiAmbientLight", &construct <NiLight> , RC_NiLight ));
|
||||
newFactory.insert(makeEntry("NiDirectionalLight", &construct <NiLight> , RC_NiLight ));
|
||||
newFactory.insert(makeEntry("NiPointLight", &construct <NiPointLight> , RC_NiLight ));
|
||||
newFactory.insert(makeEntry("NiSpotLight", &construct <NiSpotLight> , RC_NiLight ));
|
||||
newFactory.insert(makeEntry("NiTextureEffect", &construct <NiTextureEffect> , RC_NiTextureEffect ));
|
||||
newFactory.insert(makeEntry("NiVertWeightsExtraData", &construct <NiVertWeightsExtraData> , RC_NiVertWeightsExtraData ));
|
||||
newFactory.insert(makeEntry("NiTextKeyExtraData", &construct <NiTextKeyExtraData> , RC_NiTextKeyExtraData ));
|
||||
|
|
|
@ -250,5 +250,41 @@ struct NiRotatingParticles : Node
|
|||
}
|
||||
};
|
||||
|
||||
// A node used as the base to switch between child nodes, such as for LOD levels.
|
||||
struct NiSwitchNode : public NiNode
|
||||
{
|
||||
void read(NIFStream *nif)
|
||||
{
|
||||
NiNode::read(nif);
|
||||
nif->getInt(); // unknown
|
||||
}
|
||||
};
|
||||
|
||||
struct NiLODNode : public NiSwitchNode
|
||||
{
|
||||
osg::Vec3f lodCenter;
|
||||
|
||||
struct LODRange
|
||||
{
|
||||
float minRange;
|
||||
float maxRange;
|
||||
};
|
||||
std::vector<LODRange> lodLevels;
|
||||
|
||||
void read(NIFStream *nif)
|
||||
{
|
||||
NiSwitchNode::read(nif);
|
||||
lodCenter = nif->getVector3();
|
||||
unsigned int numLodLevels = nif->getUInt();
|
||||
for (unsigned int i=0; i<numLodLevels; ++i)
|
||||
{
|
||||
LODRange r;
|
||||
r.minRange = nif->getFloat();
|
||||
r.maxRange = nif->getFloat();
|
||||
lodLevels.push_back(r);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
} // Namespace
|
||||
#endif
|
||||
|
|
|
@ -36,6 +36,8 @@ enum RecordType
|
|||
{
|
||||
RC_MISSING = 0,
|
||||
RC_NiNode,
|
||||
RC_NiSwitchNode,
|
||||
RC_NiLODNode,
|
||||
RC_NiBillboardNode,
|
||||
RC_AvoidNode,
|
||||
RC_NiTriShape,
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
#include <osg/Geometry>
|
||||
#include <osg/Array>
|
||||
#include <osg/Version>
|
||||
#include <osg/LOD>
|
||||
|
||||
// resource
|
||||
#include <components/misc/stringops.hpp>
|
||||
|
@ -424,6 +425,20 @@ namespace NifOsg
|
|||
// Need to make sure that won't break transparency sorting. Check what the original engine is doing?
|
||||
}
|
||||
|
||||
osg::ref_ptr<osg::LOD> handleLodNode(const Nif::NiLODNode* niLodNode)
|
||||
{
|
||||
osg::ref_ptr<osg::LOD> lod (new osg::LOD);
|
||||
lod->setCenterMode(osg::LOD::USER_DEFINED_CENTER);
|
||||
lod->setCenter(niLodNode->lodCenter);
|
||||
for (unsigned int i=0; i<niLodNode->lodLevels.size(); ++i)
|
||||
{
|
||||
const Nif::NiLODNode::LODRange& range = niLodNode->lodLevels[i];
|
||||
lod->setRange(i, range.minRange, range.maxRange);
|
||||
}
|
||||
lod->setRangeMode(osg::LOD::DISTANCE_FROM_EYE_POINT);
|
||||
return lod;
|
||||
}
|
||||
|
||||
osg::ref_ptr<osg::Node> handleNode(const Nif::Node* nifNode, osg::Group* parentNode, Resource::TextureManager* textureManager,
|
||||
std::vector<int> boundTextures, int animflags, int particleflags, bool skipMeshes, TextKeyMap* textKeys, osg::Node* rootNode=NULL)
|
||||
{
|
||||
|
@ -555,6 +570,15 @@ namespace NifOsg
|
|||
// Optimization pass
|
||||
optimize(nifNode, node, skipMeshes);
|
||||
|
||||
|
||||
if (nifNode->recType == Nif::RC_NiLODNode)
|
||||
{
|
||||
const Nif::NiLODNode* niLodNode = static_cast<const Nif::NiLODNode*>(nifNode);
|
||||
osg::ref_ptr<osg::LOD> lod = handleLodNode(niLodNode);
|
||||
node->addChild(lod); // unsure if LOD should be above or below this node's transform
|
||||
node = lod;
|
||||
}
|
||||
|
||||
const Nif::NiNode *ninode = dynamic_cast<const Nif::NiNode*>(nifNode);
|
||||
if(ninode)
|
||||
{
|
||||
|
|
|
@ -264,7 +264,9 @@ void Emitter::emitParticles(double dt)
|
|||
osg::MatrixList worldMats = getParticleSystem()->getWorldMatrices();
|
||||
if (!worldMats.empty())
|
||||
{
|
||||
const osg::Matrix psToWorld = worldMats[0];
|
||||
osg::Matrix psToWorld = worldMats[0];
|
||||
// ignore scales in particlesystem world matrix. this seems wrong, but have to do so for MW compatibility.
|
||||
psToWorld.orthoNormalize(psToWorld);
|
||||
worldToPs = osg::Matrix::inverse(psToWorld);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue