From edf85b26f9f12298d0ce32f30a0e4addfd44b968 Mon Sep 17 00:00:00 2001
From: Jason Hooks <Hooks@.(none)>
Date: Thu, 3 Nov 2011 19:40:37 -0400
Subject: [PATCH] Insert Mesh, Insert Light, insertBegin improved

---
 apps/openmw/mwrender/objects.cpp | 95 ++++++++++++++++++++++++++++++--
 apps/openmw/mwrender/objects.hpp | 25 ++++++++-
 2 files changed, 111 insertions(+), 9 deletions(-)

diff --git a/apps/openmw/mwrender/objects.cpp b/apps/openmw/mwrender/objects.cpp
index 97e086429..963d03e12 100644
--- a/apps/openmw/mwrender/objects.cpp
+++ b/apps/openmw/mwrender/objects.cpp
@@ -1,33 +1,116 @@
 #include "objects.hpp"
 #include <OgreSceneNode.h>
+#include <components/nifogre/ogre_nif_loader.hpp>
 
 using namespace MWRender;
+using namespace Ogre;
+
+bool Objects::lightConst = false;
+float Objects::lightConstValue = 0.0f;
+
+bool Objects::lightLinear = true;
+int Objects::lightLinearMethod = 1;
+float Objects::lightLinearValue = 3;
+float Objects::lightLinearRadiusMult = 1;
+
+bool Objects::lightQuadratic = false;
+int Objects::lightQuadraticMethod = 2;
+float Objects::lightQuadraticValue = 16;
+float Objects::lightQuadraticRadiusMult = 1;
+
+bool Objects::lightOutQuadInLin = false;
+
+int Objects::uniqueID = 0;
 
 void Objects::insertBegin (const MWWorld::Ptr& ptr, bool enabled, bool static_){
-	Ogre::SceneNode* root = rend.getScene()->getRootSceneNode();
+	Ogre::SceneNode* root = mRend.getScene()->getRootSceneNode();
 	Ogre::SceneNode* cellnode;
-	if(cellSceneNodes.find(ptr.getCell()) == cellSceneNodes.end())
+	if(mCellSceneNodes.find(ptr.getCell()) == mCellSceneNodes.end())
 	{
 		//Create the scenenode and put it in the map
 		cellnode = root->createChildSceneNode();
-		cellSceneNodes[ptr.getCell()] = cellnode;
-		//assert(!cellnode->getChildIterator()->begin());  //Is this right?
+		mCellSceneNodes[ptr.getCell()] = cellnode;
 	}
 	else
 	{
-		cellnode = (cellSceneNodes.find(ptr.getCell()))->second;
+		cellnode = (mCellSceneNodes.find(ptr.getCell()))->second;
 	}
 	Ogre::SceneNode* insert = cellnode->createChildSceneNode();
-	
+	const float *f = ptr.getCellRef().pos.pos;
+  insert->setPosition(f[0], f[1], f[2]);
+  insert->setScale(ptr.getCellRef().scale, ptr.getCellRef().scale, ptr.getCellRef().scale);
+
+  // Convert MW rotation to a quaternion:
+  f = ptr.getCellRef().pos.rot;
+
+  // Rotate around X axis
+  Quaternion xr(Radian(-f[0]), Vector3::UNIT_X);
+
+  // Rotate around Y axis
+  Quaternion yr(Radian(-f[1]), Vector3::UNIT_Y);
+
+  // Rotate around Z axis
+  Quaternion zr(Radian(-f[2]), Vector3::UNIT_Z);
+
+  // Rotates first around z, then y, then x
+ insert->setOrientation(xr*yr*zr);
+	 if (!enabled)
+           insert->setVisible (false);
     ptr.getRefData().setBaseNode(insert);
 	isStatic = static_;
 
     
 }
 void Objects::insertMesh (const MWWorld::Ptr& ptr, const std::string& mesh){
+	Ogre::SceneNode* insert = mRend.getScene()->getSceneNode(ptr.getRefData().getHandle());
+	assert(insert);
+
+	NifOgre::NIFLoader::load(mesh);
+  Entity *ent = mRend.getScene()->createEntity(mesh);
+
+  if(!isStatic)
+  {
+     insert->attachObject(ent);
+  }
+  else
+  {
+      sg->addEntity(ent,insert->_getDerivedPosition(),insert->_getDerivedOrientation(),insert->_getDerivedScale());
+      sg->setRegionDimensions(Ogre::Vector3(100000,10000,100000));
+      mRend.getScene()->destroyEntity(ent);
+  }
 
 }
 void Objects::insertLight (const MWWorld::Ptr& ptr, float r, float g, float b, float radius){
+	Ogre::SceneNode* insert = mRend.getScene()->getSceneNode(ptr.getRefData().getHandle());
+	assert(insert);
+	 Ogre::Light *light = mRend.getScene()->createLight();
+  light->setDiffuseColour (r, g, b);
 
+  float cval=0.0f, lval=0.0f, qval=0.0f;
+
+  if(lightConst)
+    cval = lightConstValue;
+  if(!lightOutQuadInLin)
+  {
+    if(lightLinear)
+      radius *= lightLinearRadiusMult;
+    if(lightQuadratic)
+      radius *= lightQuadraticRadiusMult;
+
+    if(lightLinear)
+      lval = lightLinearValue / pow(radius, lightLinearMethod);
+    if(lightQuadratic)
+      qval = lightQuadraticValue / pow(radius, lightQuadraticMethod);
+  }
+  else
+  {
+    // FIXME:
+    // Do quadratic or linear, depending if we're in an exterior or interior
+    // cell, respectively. Ignore lightLinear and lightQuadratic.
+  }
+
+  light->setAttenuation(10*radius, cval, lval, qval);
+
+  insert->attachObject(light);
 }
 
diff --git a/apps/openmw/mwrender/objects.hpp b/apps/openmw/mwrender/objects.hpp
index 53a3745ed..1b1722365 100644
--- a/apps/openmw/mwrender/objects.hpp
+++ b/apps/openmw/mwrender/objects.hpp
@@ -7,11 +7,30 @@
 namespace MWRender{
 class Objects{
 private:
-	OEngine::Render::OgreRenderer &rend;
-	std::map<MWWorld::Ptr::CellStore *, Ogre::SceneNode *> cellSceneNodes;
+	OEngine::Render::OgreRenderer &mRend;
+	std::map<MWWorld::Ptr::CellStore *, Ogre::SceneNode *> mCellSceneNodes;
 	bool isStatic;
+	Ogre::StaticGeometry *sg;
+	static int uniqueID;
+	 static bool lightConst;
+    static float lightConstValue;
+
+    static bool lightLinear;
+    static int lightLinearMethod;
+    static float lightLinearValue;
+    static float lightLinearRadiusMult;
+
+    static bool lightQuadratic;
+    static int lightQuadraticMethod;
+    static float lightQuadraticValue;
+    static float lightQuadraticRadiusMult;
+
+    static bool lightOutQuadInLin;
 public:
-    Objects(OEngine::Render::OgreRenderer& _rend): rend(_rend){}
+    Objects(OEngine::Render::OgreRenderer& _rend): mRend(_rend){
+		uniqueID = uniqueID +1;
+    sg = mRend.getScene()->createStaticGeometry( "sg" + Ogre::StringConverter::toString(uniqueID));
+	}
     ~Objects(){}
    void insertBegin (const MWWorld::Ptr& ptr, bool enabled, bool static_);
     void insertMesh (const MWWorld::Ptr& ptr, const std::string& mesh);