Merge remote-tracking branch 'origin/master'

openmw-38
Marc Zinnschlag 9 years ago
commit fa9ebc50a2

@ -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
}
};
// 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 NiPointLight : public NiLight
{
float constantAttenuation;
float linearAttenuation;
float quadraticAttenuation;
void read(NIFStream *nif);
};
SLight light;
void read(NIFStream *nif);
};
struct NiSpotLight : public NiPointLight
{
float cutoff;
float exponent;
void read(NIFStream *nif);
};
struct NiTextureEffect : Effect
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…
Cancel
Save