From 901539e5944dd21b7946379ff2f7b87b433603c6 Mon Sep 17 00:00:00 2001 From: Vulpovile Date: Sat, 4 Nov 2023 23:01:43 -0700 Subject: [PATCH] Ported part and pvinstance, made XplicitNgine not use globals --- Blocks3D VS2003.vcproj | 214 +++----- src/include/DataModelV2/PartInstance.h | 5 +- src/include/DataModelV3/DataModelInstance.h | 8 +- src/include/DataModelV3/LevelInstance.h | 5 +- src/include/DataModelV3/PVInstance.h | 38 ++ src/include/DataModelV3/PartInstance.h | 101 ++++ .../DataModelV3/XplicitNgine/XplicitNgine.h | 28 ++ .../Reflection/ReflectionProperty_impl.h | 1 + src/source/DataModelV3/DataModelInstance.cpp | 9 +- src/source/DataModelV3/LevelInstance.cpp | 7 +- src/source/DataModelV3/PVInstance.cpp | 30 +- src/source/DataModelV3/PartInstance.cpp | 476 +++++++++++++++++- .../DataModelV3/XplicitNgine/XplicitNgine.cpp | 246 +++++++++ 13 files changed, 1008 insertions(+), 160 deletions(-) create mode 100644 src/include/DataModelV3/XplicitNgine/XplicitNgine.h create mode 100644 src/source/DataModelV3/XplicitNgine/XplicitNgine.cpp 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