diff --git a/Blocks3D VS2003.vcproj b/Blocks3D VS2003.vcproj
index aaa11e4..d80f152 100644
--- a/Blocks3D VS2003.vcproj
+++ b/Blocks3D VS2003.vcproj
@@ -301,13 +301,26 @@
+ Name="DataModelV2"
+ Filter="">
+
+
+
+
+
+
+
+
@@ -332,39 +345,21 @@
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
@@ -412,6 +407,9 @@
+
+
+ Name="DataModelV2"
+ Filter="">
+
+
+
+
+ ObjectFile="$(IntDir)/$(InputName)1.obj"/>
+ ObjectFile="$(IntDir)/$(InputName)1.obj"/>
+ ObjectFile="$(IntDir)/$(InputName)1.obj"/>
+ ObjectFile="$(IntDir)/$(InputName)1.obj"/>
+
+
+
+
+ ObjectFile="$(IntDir)/$(InputName)1.obj"/>
+ ObjectFile="$(IntDir)/$(InputName)1.obj"/>
+ ObjectFile="$(IntDir)/$(InputName)1.obj"/>
+ ObjectFile="$(IntDir)/$(InputName)1.obj"/>
+ ObjectFile="$(IntDir)/$(InputName)1.obj"/>
+ ObjectFile="$(IntDir)/$(InputName)1.obj"/>
+ ObjectFile="$(IntDir)/$(InputName)1.obj"/>
+ ObjectFile="$(IntDir)/$(InputName)1.obj"/>
+
+
+
+
+ ObjectFile="$(IntDir)/$(InputName)1.obj"/>
+ ObjectFile="$(IntDir)/$(InputName)1.obj"/>
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
@@ -763,6 +690,21 @@
+
+
+
+
+
+
+
+
getProperties();
- virtual void PropUpdate(LPPROPGRIDITEM &pItem);
+ std::vector getProperties();
+ void PropUpdate(LPPROPGRIDITEM &item);
private:
bool anchored;
Vector3 position;
diff --git a/src/include/DataModelV3/DataModelInstance.h b/src/include/DataModelV3/DataModelInstance.h
index 76bfb31..fa2722b 100644
--- a/src/include/DataModelV3/DataModelInstance.h
+++ b/src/include/DataModelV3/DataModelInstance.h
@@ -6,11 +6,11 @@ using namespace B3D;
// Instances
//#include "WorkspaceInstance.h"
#include "LevelInstance.h"
-//#include "PartInstance.h"
+#include "PartInstance.h"
//#include "SelectionService.h"
//#include "GuiRootInstance.h"
//#include "ThumbnailGeneratorInstance.h"
-//#include "XplicitNgine/XplicitNgine.h"
+#include "XplicitNgine/XplicitNgine.h"
//#include "SoundService.h"
//#include "LightingInstance.h"
@@ -30,7 +30,7 @@ namespace B3D {
// Instance getters
// WorkspaceInstance* getWorkspace();
LevelInstance* getLevel();
- // XplicitNgine* getEngine();
+ XplicitNgine* getEngine();
// ThumbnailGeneratorInstance* getThumbnailGenerator();
// SoundService* getSoundService();
// LightingInstance* getLighting();
@@ -55,7 +55,7 @@ namespace B3D {
// GuiRootInstance* guiRoot;
// SelectionService* selectionService;
// ThumbnailGeneratorInstance* thumbnailGenerator;
- // XplicitNgine* xplicitNgine;
+ XplicitNgine* xplicitNgine;
// SoundService* soundService;
// LightingInstance* lightingInstance;
bool running;
diff --git a/src/include/DataModelV3/LevelInstance.h b/src/include/DataModelV3/LevelInstance.h
index 201c022..7b8fa6d 100644
--- a/src/include/DataModelV3/LevelInstance.h
+++ b/src/include/DataModelV3/LevelInstance.h
@@ -1,5 +1,6 @@
#pragma once
#include "Instance.h"
+#include "Enum.h"
namespace B3D{
class LevelInstance : public Instance
{
@@ -17,8 +18,8 @@ class LevelInstance : public Instance
//Values
Reflection::ReflectionProperty highScoreIsGood;
- Reflection::ReflectionProperty timerUpAction;
- Reflection::ReflectionProperty timerAffectsScore;
+ Reflection::ReflectionProperty timerUpAction;
+ Reflection::ReflectionProperty timerAffectsScore;
Reflection::ReflectionProperty runOnOpen;
Reflection::ReflectionProperty timer;
Reflection::ReflectionProperty score;
diff --git a/src/include/DataModelV3/PVInstance.h b/src/include/DataModelV3/PVInstance.h
index e69de29..f1b64ad 100644
--- a/src/include/DataModelV3/PVInstance.h
+++ b/src/include/DataModelV3/PVInstance.h
@@ -0,0 +1,38 @@
+#pragma once
+#include "Instance.h"
+#include "Enum.h"
+#include
+
+namespace B3D {
+ class PVInstance : public Instance
+ {
+ public:
+ ~PVInstance(void);
+
+ virtual void postRender(RenderDevice* rd);
+ Reflection::ReflectionProperty nameShown;
+ Reflection::ReflectionProperty controllerFlagShown;
+ Reflection::ReflectionProperty controller;
+ protected:
+ PVInstance(void);
+ PVInstance(std::string);
+
+ Reflection::ReflectionProperty cFrame;
+ //TODO move elsewhere?
+ static G3D::Color3 getControllerColor(int controller)
+ {
+ switch(controller)
+ {
+ case Enum::Controller::KeyboardLeft:
+ return Color3::red();
+ case Enum::Controller::KeyboardRight:
+ return Color3::blue();
+ case Enum::Controller::Chase:
+ return Color3::black();
+ case Enum::Controller::Flee:
+ return Color3::yellow();
+ }
+ return Color3::gray();
+ }
+ };
+}
\ No newline at end of file
diff --git a/src/include/DataModelV3/PartInstance.h b/src/include/DataModelV3/PartInstance.h
index e69de29..3718cf0 100644
--- a/src/include/DataModelV3/PartInstance.h
+++ b/src/include/DataModelV3/PartInstance.h
@@ -0,0 +1,101 @@
+#pragma once
+#include "PVInstance.h"
+#include "Enum.h"
+#define _USE_MATH_DEFINES
+#include
+
+namespace B3D
+{
+ class PartInstance : public PVInstance
+ {
+ public:
+
+ PartInstance(void);
+ ~PartInstance(void);
+
+
+ //Reflective Properties
+ Reflection::ReflectionProperty color;
+ Reflection::ReflectionProperty canCollide;
+ //Surfaces
+ Reflection::ReflectionProperty top, front, right, back, left, bottom;
+ //Shapes
+ Reflection::ReflectionProperty shape;
+ //OnTouch
+ Reflection::ReflectionProperty onTouchAction;
+ Reflection::ReflectionProperty OnTouchSound;
+
+ //Non-Reflective Variables
+ dBodyID physBody;
+ dGeomID physGeom[3];
+
+ //Functions
+ //Rendering
+ virtual void PartInstance::postRender(RenderDevice* rd);
+ virtual void render(RenderDevice*);
+ virtual void renderName(RenderDevice*);
+ //Getters
+ Vector3 getPosition();
+ Vector3 getVelocity();
+ Vector3 getRotVelocity();
+ Vector3 getSize();
+ Box getBox();
+ Sphere getSphere();
+ Box getScaledBox();
+ CoordinateFrame getCFrame();
+
+ //OnTouch Getters
+ bool isSingleShot();
+ int getTouchesToTrigger();
+ int getUniqueObjectsToTrigger();
+ int getChangeScore();
+ float getChangeTimer();
+
+ //Setters
+ void setParent(Instance* parent);
+ void setPosition(Vector3);
+ void setVelocity(Vector3);
+ void setRotVelocity(Vector3);
+ void setCFrame(CoordinateFrame);
+ void setCFrameNoSync(CoordinateFrame);
+ void setSize(Vector3);
+ void setShape(Enum::Shape::Value shape);
+ void setChanged();
+ void setSurface(int face, Enum::SurfaceType::Value surface);
+ void setAnchored(bool anchored);
+ bool isAnchored();
+ float getMass();
+ bool isDragging();
+ void setDragging(bool value);
+
+ //Collision
+ bool collides(PartInstance * part);
+ bool collides(Box);
+
+ // onTouch
+ void onTouch();
+ private:
+ //Reflective Properties
+ Reflection::ReflectionProperty anchored;
+ Reflection::ReflectionProperty position;
+ Reflection::ReflectionProperty size;
+ Reflection::ReflectionProperty velocity;
+ Reflection::ReflectionProperty rotVelocity;
+
+ // OnTouch
+ Reflection::ReflectionProperty singleShot;
+ Reflection::ReflectionProperty touchesToTrigger;
+ Reflection::ReflectionProperty uniqueObjectsToTrigger;
+ Reflection::ReflectionProperty changeScore;
+ Reflection::ReflectionProperty changeTimer;
+
+ //Non-reflective Variables
+ bool changed;
+ bool dragging;
+ Box itemBox;
+ GLuint glList;
+ bool _touchedOnce;
+
+
+ };
+}
\ No newline at end of file
diff --git a/src/include/DataModelV3/XplicitNgine/XplicitNgine.h b/src/include/DataModelV3/XplicitNgine/XplicitNgine.h
new file mode 100644
index 0000000..4496225
--- /dev/null
+++ b/src/include/DataModelV3/XplicitNgine/XplicitNgine.h
@@ -0,0 +1,28 @@
+#pragma once
+#include
+#include "DatamodelV3/Instance.h"
+#include "DatamodelV3/PartInstance.h"
+
+namespace B3D{
+ struct PhysWorldData{
+ dWorldID physWorld;
+ dSpaceID physSpace;
+ dJointGroupID contactgroup;
+ };
+ class XplicitNgine : public Instance
+ {
+ public:
+ XplicitNgine();
+ ~XplicitNgine();
+ dWorldID physWorld;
+ dSpaceID physSpace;
+ PhysWorldData physWorldData;
+ dJointGroupID contactgroup;
+
+ void step(float stepSize);
+ void createBody(PartInstance* partInstance);
+ void deleteBody(PartInstance* partInstance);
+ void updateBody(PartInstance* partInstance);
+ void resetBody(PartInstance* partInstance);
+ };
+}
\ No newline at end of file
diff --git a/src/include/Reflection/ReflectionProperty_impl.h b/src/include/Reflection/ReflectionProperty_impl.h
index 45d8b4f..affcd11 100644
--- a/src/include/Reflection/ReflectionProperty_impl.h
+++ b/src/include/Reflection/ReflectionProperty_impl.h
@@ -34,6 +34,7 @@ ReflectionProperty::ReflectionProperty(void)
template
ReflectionProperty::~ReflectionProperty(void)
{
+ dispose();
}
template
diff --git a/src/source/DataModelV3/DataModelInstance.cpp b/src/source/DataModelV3/DataModelInstance.cpp
index 8aa0058..3022002 100644
--- a/src/source/DataModelV3/DataModelInstance.cpp
+++ b/src/source/DataModelV3/DataModelInstance.cpp
@@ -45,12 +45,10 @@ void DataModelInstance::resetEngine()
}
*/
-//TODO implement
-/*
XplicitNgine * DataModelInstance::getEngine()
{
return xplicitNgine;
-}*/
+}
void DataModelInstance::toggleRun()
{
@@ -316,11 +314,10 @@ void DataModelInstance::drawMessage(RenderDevice* rd)
return selectionService;
}*/
-//TODO implement
-/*LevelInstance* DataModelInstance::getLevel()
+LevelInstance* DataModelInstance::getLevel()
{
return level;
-}*/
+}
//TODO implement
/*ThumbnailGeneratorInstance* DataModelInstance::getThumbnailGenerator()
diff --git a/src/source/DataModelV3/LevelInstance.cpp b/src/source/DataModelV3/LevelInstance.cpp
index 0bea565..370cf94 100644
--- a/src/source/DataModelV3/LevelInstance.cpp
+++ b/src/source/DataModelV3/LevelInstance.cpp
@@ -1,6 +1,5 @@
//#include "DataModelV3/DataModelInstance.h"
#include "DataModelV3/LevelInstance.h"
-#include "Enum.h"
using namespace B3D;
LevelInstance::LevelInstance(void)
@@ -15,10 +14,10 @@ LevelInstance::LevelInstance(void)
score = Reflection::ReflectionProperty("InitialScoreValue", 0, TYPE_INT, this->dataTable);
highScoreIsGood = Reflection::ReflectionProperty("HighScoreIsGood", false, TYPE_BOOLEAN, this->dataTable);
runOnOpen = Reflection::ReflectionProperty("RunOnOpen", false, TYPE_BOOLEAN, this->dataTable);
- timerUpAction = Reflection::ReflectionProperty("TimerUpAction", Enum::ActionType::Nothing, TYPE_ENUM, this->dataTable,
- new EnumMeta(Enum::ActionType::LENGTH, Enum::ActionType::STR_TABLE));
- timerAffectsScore = Reflection::ReflectionProperty("TimerAffectsScore", Enum::AffectType::NoChange, TYPE_ENUM, this->dataTable,
+ timerUpAction = Reflection::ReflectionProperty("TimerUpAction", Enum::ActionType::Nothing, TYPE_ENUM, this->dataTable,
new EnumMeta(Enum::ActionType::LENGTH, Enum::ActionType::STR_TABLE));
+ timerAffectsScore = Reflection::ReflectionProperty("TimerAffectsScore", Enum::AffectType::NoChange, TYPE_ENUM, this->dataTable,
+ new EnumMeta(Enum::AffectType::LENGTH, Enum::AffectType::STR_TABLE));
canDelete = false;
}
diff --git a/src/source/DataModelV3/PVInstance.cpp b/src/source/DataModelV3/PVInstance.cpp
index 8d77aca..1014f34 100644
--- a/src/source/DataModelV3/PVInstance.cpp
+++ b/src/source/DataModelV3/PVInstance.cpp
@@ -1,3 +1,27 @@
-#include "DataModelV3/PVInstance.h"
-
-
+#include "DataModelV3/PVInstance.h"
+using namespace B3D;
+
+PVInstance::PVInstance(std::string className)
+{
+ Instance::Instance(className);
+
+ nameShown = Reflection::ReflectionProperty("NameShown", false, TYPE_BOOLEAN, this->dataTable);
+ controllerFlagShown = Reflection::ReflectionProperty("ControllerFlagShown", true, TYPE_BOOLEAN, this->dataTable);
+ controller = Reflection::ReflectionProperty("Controller", Enum::Controller::None, TYPE_ENUM, this->dataTable,
+ (void*)new EnumMeta(Enum::Controller::LENGTH, Enum::Controller::STR_TABLE));
+ cFrame = Reflection::ReflectionProperty("CFrame", CoordinateFrame(), TYPE_CFRAME, this->dataTable);
+
+}
+
+PVInstance::PVInstance(void)
+{
+ PVInstance::PVInstance("PVInstance");
+}
+
+PVInstance::~PVInstance(void)
+{
+}
+
+void PVInstance::postRender(RenderDevice* rd)
+{
+}
diff --git a/src/source/DataModelV3/PartInstance.cpp b/src/source/DataModelV3/PartInstance.cpp
index f591508..46a4133 100644
--- a/src/source/DataModelV3/PartInstance.cpp
+++ b/src/source/DataModelV3/PartInstance.cpp
@@ -1,3 +1,475 @@
#include "DataModelV3/PartInstance.h"
-
-
+
+#include "DataModelV3/DataModelInstance.h"
+#include "DataModelV3/XplicitNgine/XplicitNgine.h"
+
+#include "Renderer.h"
+#include
+#include
+#include "Faces.h"
+#include "AudioPlayer.h"
+#include "StringFunctions.h"
+
+using namespace B3D;
+using namespace Reflection;
+
+PartInstance::PartInstance(void)
+{
+ PVInstance::PVInstance("Part");
+
+ *(name.value) = "Unnamed PVItem";
+ canCollide = ReflectionProperty("CanCollide", true, TYPE_BOOLEAN, this->dataTable);
+ anchored = ReflectionProperty("Anchored", false, TYPE_BOOLEAN, this->dataTable);
+ size = ReflectionProperty("Size", Vector3(2,1,4), TYPE_VECTOR3, this->dataTable);
+ setCFrame(CoordinateFrame(Vector3(0,0,0)));
+ color = ReflectionProperty("Color", Color3::gray(), TYPE_COLOR3, this->dataTable);
+ velocity = ReflectionProperty("Velocity", Vector3(0,0,0), TYPE_VECTOR3, this->dataTable);
+ rotVelocity = ReflectionProperty("RotVelocity", Vector3(0,0,0), TYPE_VECTOR3, this->dataTable);
+ top = ReflectionProperty("TopSurface", Enum::SurfaceType::Bumps, TYPE_ENUM, this->dataTable,
+ (void*)new EnumMeta(Enum::SurfaceType::LENGTH, Enum::SurfaceType::STR_TABLE));
+ front = ReflectionProperty("FrontSurface", Enum::SurfaceType::Smooth, TYPE_ENUM, this->dataTable,
+ (void*)new EnumMeta(Enum::SurfaceType::LENGTH, Enum::SurfaceType::STR_TABLE));
+ right = ReflectionProperty("RightSurface", Enum::SurfaceType::Smooth, TYPE_ENUM, this->dataTable,
+ (void*)new EnumMeta(Enum::SurfaceType::LENGTH, Enum::SurfaceType::STR_TABLE));
+ back = ReflectionProperty("BackSurface", Enum::SurfaceType::Smooth, TYPE_ENUM, this->dataTable,
+ (void*)new EnumMeta(Enum::SurfaceType::LENGTH, Enum::SurfaceType::STR_TABLE));
+ left = ReflectionProperty("LeftSurface", Enum::SurfaceType::Smooth, TYPE_ENUM, this->dataTable,
+ (void*)new EnumMeta(Enum::SurfaceType::LENGTH, Enum::SurfaceType::STR_TABLE));
+ bottom = ReflectionProperty("BottomSurface", Enum::SurfaceType::Smooth, TYPE_ENUM, this->dataTable,
+ (void*)new EnumMeta(Enum::SurfaceType::LENGTH, Enum::SurfaceType::STR_TABLE));
+ shape = ReflectionProperty("Shape", Enum::Shape::Block, TYPE_ENUM, this->dataTable,
+ (void*)new EnumMeta(Enum::Shape::LENGTH, Enum::Shape::STR_TABLE));
+
+ // OnTouch
+ singleShot = ReflectionProperty("SingleShot", true, TYPE_BOOLEAN, this->dataTable);
+ touchesToTrigger = ReflectionProperty("TouchesToTrigger", 1, TYPE_INT, this->dataTable);
+ uniqueObjectsToTrigger = ReflectionProperty("UniqueObjectsToTrigger", 1, TYPE_INT, this->dataTable);
+ changeScore = ReflectionProperty("ChangeScore", 0, TYPE_INT, this->dataTable);
+ changeTimer = ReflectionProperty("ChangeTimer", 0.0f, TYPE_FLOAT, this->dataTable);
+
+ // Non-Reflective Properties
+ physBody = NULL;
+ glList = glGenLists(1);
+ _touchedOnce = false;
+ dragging = false;
+}
+
+bool PartInstance::isDragging()
+{
+ return dragging;
+}
+
+void PartInstance::setDragging(bool value)
+{
+ if (dragging != value && getParentDataModel() != NULL)
+ {
+ dragging = value;
+ //TODO implement engine
+ //getParentDataModel()->getEngine()->resetBody(this);
+ }
+}
+
+float PartInstance::getMass()
+{
+ if(*(shape.value) == Enum::Shape::Block)
+ return size.value->x*size.value->y*size.value->z*0.7F;
+ else
+ return 1.3333333333333333333333333333333F*(size.value->x/2)*(size.value->y/2)*(size.value->z/2)*0.7F;
+}
+
+Vector3 PartInstance::getVelocity()
+{
+ return *(velocity.value);
+}
+Vector3 PartInstance::getRotVelocity()
+{
+ return *(rotVelocity.value);
+}
+
+// OnTouch
+bool PartInstance::isSingleShot()
+{
+ return *(singleShot.value);
+}
+
+int PartInstance::getTouchesToTrigger()
+{
+ return *(touchesToTrigger.value);
+}
+
+int PartInstance::getUniqueObjectsToTrigger()
+{
+ return *(uniqueObjectsToTrigger.value);
+}
+
+int PartInstance::getChangeScore()
+{
+ return *(changeScore.value);
+}
+
+float PartInstance::getChangeTimer()
+{
+ return *(changeTimer.value);
+}
+
+void PartInstance::setVelocity(Vector3 v)
+{
+ *(velocity.value) = v;
+}
+void PartInstance::setRotVelocity(Vector3 v)
+{
+ *(rotVelocity.value) = v;
+}
+
+void PartInstance::postRender(RenderDevice *rd)
+{
+ // possibly discard this function...
+}
+
+void PartInstance::renderName(RenderDevice *rd)
+{
+ if(!*(nameShown.value))
+ return;
+ G3D::GFontRef fnt = NULL;
+ Instance* dm = parent;
+ while(dm != NULL)
+ {
+ if(DataModelInstance* mod = dynamic_cast(dm))
+ {
+ fnt = mod->font;
+ break;
+ }
+ dm = dm->getParent();
+ }
+ if(!fnt.isNull())
+ {
+ Vector3 gamepoint = *(position.value) + Vector3(0,1.5,0);
+ Vector3 camerapoint = rd->getCameraToWorldMatrix().translation;
+ float distance = pow(pow((double)gamepoint.x - (double)camerapoint.x, 2) + pow((double)gamepoint.y - (double)camerapoint.y, 2) + pow((double)gamepoint.z - (double)camerapoint.z, 2), 0.5);
+ if(distance < 100 && distance > -100)
+ {
+ if(distance < 0)
+ distance = distance*-1;
+ glDisable(GL_DEPTH_TEST);
+ fnt->draw3D(rd, *(name.value), CoordinateFrame(rd->getCameraToWorldMatrix().rotation, gamepoint), 0.03*distance, Color3::yellow(), Color3::black(), G3D::GFont::XALIGN_CENTER, G3D::GFont::YALIGN_CENTER);
+ glEnable(GL_DEPTH_TEST);
+ }
+ }
+}
+
+void PartInstance::setChanged()
+{
+ changed = true;
+}
+
+void PartInstance::setSurface(int face, Enum::SurfaceType::Value surface)
+{
+ switch(face)
+ {
+ case TOP:
+ *(top.value) = surface;
+ break;
+ case BOTTOM:
+ *(bottom.value) = surface;
+ break;
+ case LEFT:
+ *(left.value) = surface;
+ break;
+ case RIGHT:
+ *(right.value) = surface;
+ break;
+ case FRONT:
+ *(front.value) = surface;
+ break;
+ default:
+ *(back.value) = surface;
+ }
+ changed = true;
+}
+
+void PartInstance::setParent(Instance* prnt)
+{
+ if(this->physBody != NULL && getParentDataModel() != NULL)
+ {
+ //TODO implement engine
+ //getParentDataModel()->getEngine()->deleteBody(this);
+ }
+ Instance * cparent = getParent();
+ //TODO implement workspace
+ /*while(cparent != NULL)
+ {
+ if(WorkspaceInstance* workspace = dynamic_cast(cparent))
+ {
+ workspace->partObjects.erase(std::remove(workspace->partObjects.begin(), workspace->partObjects.end(), this), workspace->partObjects.end());
+ }
+ cparent = cparent->getParent();
+ }*/
+ Instance::setParent(prnt);
+ cparent = getParent();
+ //TODO implement workspace
+ /*
+ while(cparent != NULL)
+ {
+ if(WorkspaceInstance* workspace = dynamic_cast(cparent))
+ {
+ workspace->partObjects.push_back(this);
+ break;
+ }
+ cparent = cparent->getParent();
+ }*/
+
+}
+
+void PartInstance::setSize(Vector3 newSize)
+{
+ int minsize = 1;
+ int maxsize = 512;
+ changed = true;
+ int sizex = (int)newSize.x;
+ if(sizex <= 0)
+ sizex = 1;
+ if(sizex > 512)
+ sizex = 512;
+
+ int sizey = (int)newSize.y;
+ if(sizey <= 0)
+ sizey = 1;
+ if(sizey > 512)
+ sizey = 512;
+
+ int sizez = (int)newSize.z;
+ if(sizez <= 0)
+ sizez = 1;
+ if(sizez > 512)
+ sizez = 512;
+
+ if(*(shape.value) != Enum::Shape::Block)
+ {
+ int max = sizex;
+ if(sizey > max)
+ max = sizey;
+ if(sizez > max)
+ max = sizez;
+ sizex = sizey = sizez = max;
+ }
+
+ *(size.value) = Vector3(sizex, sizey, sizez);
+
+ if(this->physBody != NULL && getParentDataModel() != NULL)
+ getParentDataModel()->getEngine()->resetBody(this);
+}
+Vector3 PartInstance::getSize()
+{
+ return *(size.value);
+}
+Vector3 PartInstance::getPosition()
+{
+ return *(position.value);
+}
+void PartInstance::setShape(Enum::Shape::Value shape)
+{
+ switch(shape)
+ {
+ case Enum::Shape::Block:
+ *(this->shape.value) = shape;
+ break;
+ default:
+ *(this->shape.value) = shape;
+ this->setSize(this->getSize());
+ }
+ if(this->physBody != NULL && getParentDataModel() != NULL)
+ getParentDataModel()->getEngine()->resetBody(this);
+
+ changed = true;
+}
+
+void PartInstance::setPosition(Vector3 pos)
+{
+ *(position.value) = pos;
+ setCFrame(CoordinateFrame(cFrame.value->rotation, pos));
+
+ if (*(anchored.value) && getParentDataModel() != NULL)
+ getParentDataModel()->getEngine()->resetBody(this);
+}
+
+void PartInstance::setAnchored(bool anchored)
+{
+ *(this->anchored.value) = anchored;
+ if(this->physBody != NULL && getParentDataModel() != NULL)
+ getParentDataModel()->getEngine()->resetBody(this);
+}
+
+bool PartInstance::isAnchored()
+{
+ return *(this->anchored.value);
+}
+
+
+CoordinateFrame PartInstance::getCFrame()
+{
+ return cFrame.value->rotation;
+}
+void PartInstance::setCFrame(CoordinateFrame coordinateFrame)
+{
+ setCFrameNoSync(coordinateFrame);
+ if(getParentDataModel() != NULL)
+ getParentDataModel()->getEngine()->updateBody(this);
+}
+
+void PartInstance::setCFrameNoSync(CoordinateFrame coordinateFrame)
+{
+ *(cFrame.value) = coordinateFrame;
+ *(position.value) = coordinateFrame.translation;
+}
+
+bool PartInstance::collides(PartInstance * part)
+{
+ if(*(shape.value) == Enum::Shape::Block)
+ {
+ if(*(part->shape.value) == Enum::Shape::Block)
+ return G3D::CollisionDetection::fixedSolidBoxIntersectsFixedSolidBox(getBox(), part->getBox());
+ else
+ return G3D::CollisionDetection::fixedSolidSphereIntersectsFixedSolidBox(part->getSphere(), getBox());
+ }
+ else
+ {
+ if(*(part->shape.value) == Enum::Shape::Block)
+ return G3D::CollisionDetection::fixedSolidSphereIntersectsFixedSolidBox(getSphere(), part->getBox());
+ else
+ return G3D::CollisionDetection::fixedSolidSphereIntersectsFixedSolidSphere(getSphere(), part->getSphere());
+ }
+}
+
+Box PartInstance::getBox()
+{
+ Box box = Box(Vector3(size.value->x/2, size.value->y/2, size.value->z/2) ,Vector3(-size.value->x/2,-size.value->y/2,-size.value->z/2));
+ CoordinateFrame c = getCFrame();
+ itemBox = c.toWorldSpace(box);
+ return itemBox;
+}
+
+Sphere PartInstance::getSphere()
+{
+ Sphere sphere = Sphere(Vector3(0,0,0), size.value->y/2);
+ CoordinateFrame c = getCFrame();
+ return sphere;
+}
+
+bool PartInstance::collides(Box box)
+{
+ return CollisionDetection::fixedSolidBoxIntersectsFixedSolidBox(getBox(), box);
+}
+
+void PartInstance::render(RenderDevice* rd) {
+ if (changed)
+ {
+ changed=false;
+ Vector3 renderSize = *(size.value)/2;
+ glNewList(glList, GL_COMPILE);
+ renderShape(*(this->shape.value), renderSize, *(color.value));
+ renderSurface(TOP, *(this->top.value), renderSize, *(this->controller.value), *(color.value));
+ renderSurface(FRONT, *(this->front.value), renderSize, *(this->controller.value), *(color.value));
+ renderSurface(RIGHT, *(this->right.value), renderSize, *(this->controller.value), *(color.value));
+ renderSurface(BACK, *(this->back.value), renderSize, *(this->controller.value), *(color.value));
+ renderSurface(LEFT, *(this->left.value), renderSize, *(this->controller.value), *(color.value));
+ renderSurface(BOTTOM, *(this->bottom.value), renderSize, *(this->controller.value), *(color.value));
+ glEndList();
+ }
+ rd->setObjectToWorldMatrix(*(cFrame.value));
+ glCallList(glList);
+ postRender(rd);
+}
+
+PartInstance::~PartInstance(void)
+{
+ glDeleteLists(glList, 1);
+ /*
+ // Causes some weird ODE error
+ // Someone, please look into this
+
+ dBodyDestroy(physBody);
+ for (int i = 0; i < 3; i++) {
+ if (physGeom[i] != NULL)
+ dGeomDestroy(physGeom[i]);
+ }
+ */
+}
+
+void PartInstance::onTouch()
+{
+ if(getParentDataModel() == NULL)
+ return;
+ if(*(singleShot.value) && _touchedOnce)
+ return;
+
+ if(*(singleShot.value) && !_touchedOnce)
+ _touchedOnce = true;
+
+ *(getParentDataModel()->getLevel()->score.value) += *(changeScore.value);
+ *(getParentDataModel()->getLevel()->timer.value) += *(changeTimer.value);
+
+ switch(*(onTouchAction.value))
+ {
+ case Enum::ActionType::Nothing:
+ break;
+ case Enum::ActionType::Pause:
+ break;
+ case Enum::ActionType::Lose:
+ getParentDataModel()->getLevel()->loseCondition();
+ break;
+ case Enum::ActionType::Draw:
+ break;
+ case Enum::ActionType::Win:
+ getParentDataModel()->getLevel()->winCondition();
+ break;
+ }
+
+ //TODO implement SoundService
+ /*
+ SoundService* sndService = getParentDataModel()->getSoundService();
+
+ switch(OnTouchSound)
+ {
+ case Enum::Sound::NoSound:
+ break;
+ case Enum::Sound::Victory:
+ sndService->playSound(sndService->findFirstChild("Victory"));
+ break;
+ case Enum::Sound::Boing:
+ sndService->playSound(sndService->findFirstChild("Boing"));
+ break;
+ case Enum::Sound::Break:
+ sndService->playSound(sndService->findFirstChild("Break"));
+ break;
+ case Enum::Sound::Snap:
+ sndService->playSound(sndService->findFirstChild("Snap"));
+ break;
+ case Enum::Sound::Bomb:
+ sndService->playSound(sndService->findFirstChild("Bomb"));
+ break;
+ case Enum::Sound::Splat:
+ sndService->playSound(sndService->findFirstChild("Splat"));
+ break;
+ case Enum::Sound::Page:
+ sndService->playSound(sndService->findFirstChild("Page"));
+ break;
+ case Enum::Sound::Ping:
+ sndService->playSound(sndService->findFirstChild("Ping"));
+ break;
+ case Enum::Sound::Swoosh:
+ sndService->playSound(sndService->findFirstChild("Swoosh"));
+ break;
+ case Enum::Sound::Click:
+ sndService->playSound(sndService->findFirstChild("Click"));
+ break;
+ case Enum::Sound::Clock:
+ sndService->playSound(sndService->findFirstChild("Clock"));
+ break;
+ case Enum::Sound::Step:
+ sndService->playSound(sndService->findFirstChild("Step"));
+ break;
+ case Enum::Sound::StepOn:
+ sndService->playSound(sndService->findFirstChild("StepOn"));
+ break;
+ }*/
+}
diff --git a/src/source/DataModelV3/XplicitNgine/XplicitNgine.cpp b/src/source/DataModelV3/XplicitNgine/XplicitNgine.cpp
new file mode 100644
index 0000000..f353355
--- /dev/null
+++ b/src/source/DataModelV3/XplicitNgine/XplicitNgine.cpp
@@ -0,0 +1,246 @@
+#include "DataModelV3/XplicitNgine/XplicitNgine.h"
+
+#include "DataModelV3/DataModelInstance.h"
+
+using namespace B3D;
+
+XplicitNgine::XplicitNgine()
+{
+
+ physWorld = dWorldCreate();
+ physSpace = dHashSpaceCreate(0);
+
+ physWorldData.physWorld = physWorld;
+ physWorldData.physSpace = physSpace;
+
+ contactgroup = dJointGroupCreate(0);
+ physWorldData.contactgroup = contactgroup;
+
+ dWorldSetGravity(physWorld, 0, -9.8F, 0);
+ dWorldSetAutoDisableFlag(physWorld, 1);
+ dWorldSetAutoDisableLinearThreshold(physWorld, 0.5F);
+ dWorldSetAutoDisableAngularThreshold(physWorld, 0.5F);
+ dWorldSetAutoDisableSteps(physWorld, 20);
+
+ *(this->name.value) = "PhysicsService";
+}
+
+XplicitNgine::~XplicitNgine()
+{
+ dJointGroupDestroy (contactgroup);
+ dSpaceDestroy (physSpace);
+ dWorldDestroy (physWorld);
+ dCloseODE();
+}
+
+void XplicitNgine::resetBody(PartInstance* partInstance)
+{
+ deleteBody(partInstance);
+ createBody(partInstance);
+}
+
+void collisionCallback2(void *data, dGeomID o1, dGeomID o2)
+{
+ int i,n;
+
+ PhysWorldData * physWorldData = (PhysWorldData *)data;
+
+ dBodyID b1 = dGeomGetBody(o1);
+ dBodyID b2 = dGeomGetBody(o2);
+
+ if (b1 && b2 && dAreConnected(b1, b2))
+ return;
+
+
+
+ const int N = 4;
+ dContact contact[N];
+ n = dCollide (o1,o2,N,&contact[0].geom,sizeof(dContact));
+ if (n > 0) {
+ for (i=0; iphysWorld,
+ physWorldData->contactgroup,
+ contact+i
+ );
+
+ dJointAttach (c,b1,b2);
+
+ if(b1 != NULL)
+ {
+ PartInstance* touched = (PartInstance*)dGeomGetData(o2);
+ if(touched != NULL)
+ {
+ touched->onTouch();
+ }
+ }
+ }
+ }
+}
+
+void XplicitNgine::deleteBody(PartInstance* partInstance)
+{
+ if(partInstance->physBody != NULL)
+ {
+ dBodyEnable(partInstance->physBody);
+ dGeomEnable(partInstance->physGeom[0]);
+ if(partInstance->isAnchored() || partInstance->isDragging())
+ {
+ dGeomSetBody(partInstance->physGeom[0], partInstance->physBody);
+ dGeomEnable(partInstance->physGeom[0]);
+ updateBody(partInstance);
+ step(0.03F);
+ }
+
+ for(int i = 0; i < dBodyGetNumJoints(partInstance->physBody); i++) {
+ dBodyID b1 = dJointGetBody(dBodyGetJoint(partInstance->physBody, i), 0);
+ dBodyID b2 = dJointGetBody(dBodyGetJoint(partInstance->physBody, i), 1);
+
+ if(b1 != NULL)
+ {
+ dBodyEnable(b1);
+ PartInstance * part = (PartInstance *)dBodyGetData(b1);
+ if(part != NULL)
+ dGeomEnable(part->physGeom[0]);
+ }
+
+ if(b2 != NULL)
+ {
+ dBodyEnable(b2);
+ PartInstance * part = (PartInstance *)dBodyGetData(b2);
+ if(part != NULL)
+ dGeomEnable(part->physGeom[0]);
+ }
+ dJointDestroy(dBodyGetJoint(partInstance->physBody, i));
+ }
+ dBodyDestroy(partInstance->physBody);
+ dGeomDestroy(partInstance->physGeom[0]);
+ partInstance->physBody = NULL;
+ }
+}
+
+void XplicitNgine::createBody(PartInstance* partInstance)
+{
+ if(partInstance->physBody == NULL)
+ {
+
+ Vector3 partSize = partInstance->getSize();
+ Vector3 partPosition = partInstance->getPosition();
+ Vector3 velocity = partInstance->getVelocity();
+ Vector3 rotVelocity = partInstance->getRotVelocity();
+
+ // init body
+ partInstance->physBody = dBodyCreate(physWorld);
+ dBodySetData(partInstance->physBody, partInstance);
+
+
+ // Create geom
+ if(*(partInstance->shape.value) == Enum::Shape::Block)
+ {
+ partInstance->physGeom[0] = dCreateBox(physSpace,
+ partSize.x,
+ partSize.y,
+ partSize.z
+ );
+
+ dVector3 result;
+ dGeomBoxGetLengths(partInstance->physGeom[0], result);
+ }
+ else
+ {
+ partInstance->physGeom[0] = dCreateSphere(physSpace, partSize[0]/2);
+ }
+
+ if(partInstance->physGeom[0])
+ dGeomSetData(partInstance->physGeom[0], partInstance);
+
+ dMass mass;
+ mass.setBox(sqrt(partSize.x*2), sqrt(partSize.y*2), sqrt(partSize.z*2), 0.7F);
+ dBodySetMass(partInstance->physBody, &mass);
+
+ // Create rigid body
+ dBodySetPosition(partInstance->physBody,
+ partPosition.x,
+ partPosition.y,
+ partPosition.z
+ );
+
+ dGeomSetPosition(partInstance->physGeom[0],
+ partPosition.x,
+ partPosition.y,
+ partPosition.z);
+
+ dBodySetLinearVel(partInstance->physBody, velocity.x, velocity.y, velocity.z);
+ dBodySetAngularVel(partInstance->physBody, rotVelocity.x, rotVelocity.y, rotVelocity.z);
+
+ Matrix3 g3dRot = partInstance->getCFrame().rotation;
+ float rotation [12] = { g3dRot[0][0], g3dRot[0][1], g3dRot[0][2], 0,
+ g3dRot[1][0], g3dRot[1][1], g3dRot[1][2], 0,
+ g3dRot[2][0], g3dRot[2][1], g3dRot[2][2], 0};
+ dGeomSetRotation(partInstance->physGeom[0], rotation);
+ dBodySetRotation(partInstance->physBody, rotation);
+
+ if(!partInstance->isAnchored() && !partInstance->isDragging())
+ dGeomSetBody(partInstance->physGeom[0], partInstance->physBody);
+
+ } else {
+ if(!partInstance->isAnchored() && !partInstance->isDragging())
+ {
+ const dReal* velocity = dBodyGetLinearVel(partInstance->physBody);
+ const dReal* rotVelocity = dBodyGetAngularVel(partInstance->physBody);
+
+ partInstance->setVelocity(Vector3(velocity[0],velocity[1],velocity[2]));
+ partInstance->setRotVelocity(Vector3(rotVelocity[0],rotVelocity[1],rotVelocity[2]));
+
+ const dReal* physPosition = dBodyGetPosition(partInstance->physBody);
+
+ const dReal* physRotation = dGeomGetRotation(partInstance->physGeom[0]);
+ partInstance->setCFrameNoSync(CoordinateFrame(
+ Matrix3(physRotation[0],physRotation[1],physRotation[2],
+ physRotation[4],physRotation[5],physRotation[6],
+ physRotation[8],physRotation[9],physRotation[10]),
+ Vector3(physPosition[0], physPosition[1], physPosition[2])));
+ }
+ }
+}
+
+void XplicitNgine::step(float stepSize)
+{
+ dJointGroupEmpty(contactgroup);
+ dSpaceCollide (physSpace,&physWorldData,&collisionCallback2);
+ dWorldQuickStep(physWorld, stepSize);
+}
+
+void XplicitNgine::updateBody(PartInstance *partInstance)
+{
+ if(partInstance->physBody != NULL)
+ {
+ Vector3 position = partInstance->getCFrame().translation;
+
+ dBodySetPosition(partInstance->physBody,
+ position[0],
+ position[1],
+ position[2]
+ );
+ dBodyEnable(partInstance->physBody);
+ dGeomEnable(partInstance->physGeom[0]);
+
+ Matrix3 g3dRot = partInstance->getCFrame().rotation;
+ float rotation [12] = { g3dRot[0][0], g3dRot[0][1], g3dRot[0][2], 0,
+ g3dRot[1][0], g3dRot[1][1], g3dRot[1][2], 0,
+ g3dRot[2][0], g3dRot[2][1], g3dRot[2][2], 0};
+
+ dBodySetRotation(partInstance->physBody, rotation);
+ }
+}
\ No newline at end of file