diff --git a/Projects/Client/Common/Source/OgreWidget.cpp b/Projects/Client/Common/Source/OgreWidget.cpp index f98dabe..8e4dbf2 100644 --- a/Projects/Client/Common/Source/OgreWidget.cpp +++ b/Projects/Client/Common/Source/OgreWidget.cpp @@ -97,7 +97,7 @@ namespace RNR pFont->setTrueTypeSize(16); pFont->load(); - ogreSceneManager->setShadowTechnique(Ogre::ShadowTechnique::SHADOWTYPE_STENCIL_MODULATIVE); + ogreSceneManager->setShadowTechnique(Ogre::ShadowTechnique::SHADOWTYPE_STENCIL_ADDITIVE); ogreSceneManager->setShadowFarDistance(500.f); ogreSceneLight = ogreSceneManager->createLight("SunLight"); diff --git a/Projects/Engine/CMakeLists.txt b/Projects/Engine/CMakeLists.txt index f436faa..7eb355a 100644 --- a/Projects/Engine/CMakeLists.txt +++ b/Projects/Engine/CMakeLists.txt @@ -3,6 +3,7 @@ add_library(Engine STATIC Header/Helpers/Strings.hpp Header/Helpers/XML.hpp Header/Helpers/NormalId.hpp + Header/Helpers/Bullet.hpp Header/App/Script/ReflectionProperty.hpp Header/App/Script/Script.hpp Header/App/Script/ScriptContext.hpp @@ -37,6 +38,7 @@ add_library(Engine STATIC Source/Helpers/Strings.cpp Source/Helpers/XML.cpp Source/Helpers/NormalId.cpp + Source/Helpers/Bullet.cpp Source/App/Script/ReflectionProperty.cpp Source/App/Script/Script.cpp Source/App/GUI/GuiBase3d.cpp diff --git a/Projects/Engine/Header/App/V8/DataModel/PartInstance.hpp b/Projects/Engine/Header/App/V8/DataModel/PartInstance.hpp index ca1657d..1d136c0 100644 --- a/Projects/Engine/Header/App/V8/DataModel/PartInstance.hpp +++ b/Projects/Engine/Header/App/V8/DataModel/PartInstance.hpp @@ -13,6 +13,7 @@ namespace RNR int m_brickColor; float m_transparency; float m_reflectance; + bool m_anchored; Ogre::Matrix4 m_matrix; Ogre::Vector3 m_position; Ogre::Vector3 m_size; @@ -34,6 +35,8 @@ namespace RNR float getReflectance() { return m_reflectance; } void setTransparency(float transparency) { m_transparency = transparency; } float getTransparency() { return m_transparency; } + void setAnchored(bool anchored) { m_anchored = anchored; } + bool getAnchored() { return m_anchored; } Ogre::Vector3 getOgreCenter() { return m_position + (m_size / 2.f); } diff --git a/Projects/Engine/Header/App/V8/World/World.hpp b/Projects/Engine/Header/App/V8/World/World.hpp index 0537c08..d0617a6 100644 --- a/Projects/Engine/Header/App/V8/World/World.hpp +++ b/Projects/Engine/Header/App/V8/World/World.hpp @@ -18,6 +18,7 @@ namespace RNR { class IInputManager; + class PartInstance; struct WorldUndeserialized { @@ -68,5 +69,8 @@ namespace RNR void setRunService(RunService* runService) { m_runService = runService; } Ogre::Root* getOgreRoot() { return m_ogreRoot; } Ogre::SceneManager* getOgreSceneManager() { return m_ogreSceneManager; } + + void registerPhysicsPart(PartInstance* partRegistered); + void deletePhysicsPart(PartInstance* partDelete); }; } \ No newline at end of file diff --git a/Projects/Engine/Header/Helpers/Bullet.hpp b/Projects/Engine/Header/Helpers/Bullet.hpp new file mode 100644 index 0000000..d3b6e79 --- /dev/null +++ b/Projects/Engine/Header/Helpers/Bullet.hpp @@ -0,0 +1,16 @@ +#pragma once +#include "LinearMath/btVector3.h" +#include "btBulletDynamicsCommon.h" +#include + +namespace RNR +{ + class Bullet + { + public: + static btVector3 v3ToBullet(Ogre::Vector3 v); + static Ogre::Vector3 v3ToOgre(btVector3 v); + static btQuaternion qtToBullet(Ogre::Quaternion q); + static Ogre::Quaternion qtToOgre(btQuaternion q); + }; +} \ No newline at end of file diff --git a/Projects/Engine/Source/App/GUI/TopMenuBar.cpp b/Projects/Engine/Source/App/GUI/TopMenuBar.cpp index 3457d27..6760da6 100644 --- a/Projects/Engine/Source/App/GUI/TopMenuBar.cpp +++ b/Projects/Engine/Source/App/GUI/TopMenuBar.cpp @@ -128,11 +128,12 @@ namespace RNR snprintf(render_debugtext, 255, "using BATCH_STATIC_GEOMETRY\nGeom Regions: %i", workspace->m_geom->getRegions().size()); break; } - snprintf(debugtext, 512, "Render\nLast DT = %f\n%s\n\nPhysics\n%i objects, %i constraints", + snprintf(debugtext, 512, "Render\nLast DT = %f\n%s\n\nPhysics\n%i objects, %i constraints\nRunService: running = %s, paused = %s", m_world->getLastDelta(), render_debugtext, - m_world->getOgreSceneManager(), - dynamicsWorld->getNumCollisionObjects(), dynamicsWorld->getNumConstraints()); + dynamicsWorld->getNumCollisionObjects(), dynamicsWorld->getNumConstraints(), + m_world->getRunService()->getRunning() ? "true" : "false", + m_world->getRunService()->getPaused() ? "true" : "false"); m_debugText->setCaption(debugtext); Players* players = (Players*)m_world->getDatamodel()->getService("Players"); diff --git a/Projects/Engine/Source/App/V8/DataModel/PartInstance.cpp b/Projects/Engine/Source/App/V8/DataModel/PartInstance.cpp index bec7c7c..7167f15 100644 --- a/Projects/Engine/Source/App/V8/DataModel/PartInstance.cpp +++ b/Projects/Engine/Source/App/V8/DataModel/PartInstance.cpp @@ -33,7 +33,9 @@ namespace RNR { subentity->setMaterial(BrickColor::material(m_brickColor)); subentity->getMaterial()->setShininess(64); + subentity->getMaterial()->setLightingEnabled(true); } + entity->setCastShadows(true); } void PartInstance::deserializeProperty(char* prop_name, pugi::xml_node node) @@ -58,6 +60,10 @@ namespace RNR { setTransparency(node.text().as_float()); } + else if(prop_name == std::string("Anchored")) + { + setAnchored(node.text().as_bool()); + } else PVInstance::deserializeProperty(prop_name, node); updateMatrix(); diff --git a/Projects/Engine/Source/App/V8/DataModel/Workspace.cpp b/Projects/Engine/Source/App/V8/DataModel/Workspace.cpp index 1ad8055..c102be6 100644 --- a/Projects/Engine/Source/App/V8/DataModel/Workspace.cpp +++ b/Projects/Engine/Source/App/V8/DataModel/Workspace.cpp @@ -57,6 +57,7 @@ namespace RNR case BATCH_DONT: break; } + world->registerPhysicsPart(part); } } @@ -75,6 +76,9 @@ namespace RNR void Workspace::onDescendantRemoved(Instance* childRemoved) { + PartInstance* part = dynamic_cast(childRemoved); + if(part) + world->deletePhysicsPart(part); m_geomDirty = true; } diff --git a/Projects/Engine/Source/App/V8/World/World.cpp b/Projects/Engine/Source/App/V8/World/World.cpp index 85b7ee3..fb3492e 100644 --- a/Projects/Engine/Source/App/V8/World/World.cpp +++ b/Projects/Engine/Source/App/V8/World/World.cpp @@ -8,6 +8,7 @@ #include #include #include +#include namespace RNR { @@ -20,7 +21,7 @@ namespace RNR btBroadphaseInterface* overlappingPairCache = new btDbvtBroadphase(); btSequentialImpulseConstraintSolver* solver = new btSequentialImpulseConstraintSolver; m_dynamicsWorld = new btDiscreteDynamicsWorld(dispatcher, overlappingPairCache, solver, collisionConfiguration); - m_dynamicsWorld->setGravity(btVector3(0, -10, 0)); + m_dynamicsWorld->setGravity(btVector3(0, -64, 0)); m_inputManager = 0; @@ -118,7 +119,6 @@ namespace RNR WorldUndeserialized s = m_undeserialized.top(); m_undeserialized.pop(); - s.instance->setParent(s.parent); pugi::xml_node props = s.node.child("Properties"); for(pugi::xml_node prop : props.children()) @@ -126,6 +126,8 @@ namespace RNR s.instance->deserializeXmlProperty(prop); } + s.instance->setParent(s.parent); + if(s.instance->getClassName() == "Model") { ModelInstance* m = (ModelInstance*)s.instance; @@ -149,10 +151,34 @@ namespace RNR double World::step(float timestep) { - if(m_runService && m_runService->getRunning()) + if(m_runService && m_runService->getRunning() && !m_runService->getPaused()) { m_runService->step(timestep); - m_dynamicsWorld->stepSimulation(timestep); + m_dynamicsWorld->stepSimulation(timestep, 4, 1.0/60.0); + + for(int j = m_dynamicsWorld->getNumCollisionObjects() - 1; j >= 0; j--) + { + btCollisionObject* obj = m_dynamicsWorld->getCollisionObjectArray()[j]; + if(!obj->isActive()) + continue; + btRigidBody* body = btRigidBody::upcast(obj); + btTransform trans; + if(body && body->getMotionState()) + { + body->getMotionState()->getWorldTransform(trans); + } + else + { + trans = obj->getWorldTransform(); + } + PartInstance* part = (PartInstance*)obj->getUserPointer(); + part->getCFrame().setPosition(Bullet::v3ToOgre(trans.getOrigin())); + Ogre::Matrix3 partRot; + Ogre::Quaternion transOgre = Bullet::qtToOgre(trans.getRotation()); + transOgre.ToRotationMatrix(partRot); + part->getCFrame().setRotation(partRot); + part->updateMatrix(); + } } m_lastDelta = timestep; return 0.0; @@ -162,4 +188,34 @@ namespace RNR { m_workspace->buildGeom(); } + + void World::registerPhysicsPart(PartInstance* partRegistered) + { + btCollisionShape* partShape = new btBoxShape(Bullet::v3ToBullet(partRegistered->getSize() / 2.f)); + partShape->setUserPointer(partRegistered); + + btTransform partTransform; + partTransform.setIdentity(); + partTransform.setOrigin(Bullet::v3ToBullet(partRegistered->getPosition())); + partTransform.setRotation(Bullet::qtToBullet(partRegistered->getRotation())); + + btScalar mass = partRegistered->getSize().length(); + if(partRegistered->getAnchored()) + mass = 0; + + btVector3 localInertia = btVector3(0,0,0); + if(mass) + partShape->calculateLocalInertia(mass, localInertia); + btDefaultMotionState* partMotionState = new btDefaultMotionState(partTransform); + btRigidBody::btRigidBodyConstructionInfo rbInfo(mass, partMotionState, partShape, localInertia); + btRigidBody* body = new btRigidBody(rbInfo); + body->setUserPointer(partRegistered); + + m_dynamicsWorld->addRigidBody(body); + } + + void World::deletePhysicsPart(PartInstance* partDelete) + { + + } } \ No newline at end of file diff --git a/Projects/Engine/Source/Helpers/Bullet.cpp b/Projects/Engine/Source/Helpers/Bullet.cpp new file mode 100644 index 0000000..fb13288 --- /dev/null +++ b/Projects/Engine/Source/Helpers/Bullet.cpp @@ -0,0 +1,24 @@ +#include + +namespace RNR +{ + btVector3 Bullet::v3ToBullet(Ogre::Vector3 v) + { + return btVector3(v.x, v.y, v.z); + } + + Ogre::Vector3 Bullet::v3ToOgre(btVector3 v) + { + return Ogre::Vector3(v.getX(), v.getY(), v.getZ()); + } + + btQuaternion Bullet::qtToBullet(Ogre::Quaternion q) + { + return btQuaternion(q.x, q.y, q.z, q.w); + } + + Ogre::Quaternion Bullet::qtToOgre(btQuaternion q) + { + return Ogre::Quaternion(q.getW(), q.getX(), q.getY(), q.getZ()); + } +} \ No newline at end of file