Added separate game file
This commit is contained in:
901
Game.cpp
Normal file
901
Game.cpp
Normal file
@@ -0,0 +1,901 @@
|
||||
#include <iostream>
|
||||
|
||||
#include <Ogre.h>
|
||||
#include <OgreApplicationContext.h>
|
||||
#include <OgreOverlaySystem.h>
|
||||
#include <OgreOverlayManager.h>
|
||||
#include <OgreImGuiOverlay.h>
|
||||
#include <OgreImGuiInputListener.h>
|
||||
#include <OgreTrays.h>
|
||||
#include <OgreTimer.h>
|
||||
#include <OgreMeshLodGenerator.h>
|
||||
|
||||
#include "src/terrain/terrain.h"
|
||||
#include "water/water.h"
|
||||
class App;
|
||||
class SkyRenderer : public Ogre::SceneManager::Listener {
|
||||
protected:
|
||||
Ogre::SceneManager *mSceneManager;
|
||||
virtual void _updateRenderQueue(Ogre::RenderQueue *queue) = 0;
|
||||
|
||||
public:
|
||||
enum BoxPlane {
|
||||
BP_FRONT = 0,
|
||||
BP_BACK = 1,
|
||||
BP_LEFT = 2,
|
||||
BP_RIGHT = 3,
|
||||
BP_UP = 4,
|
||||
BP_DOWN = 5
|
||||
};
|
||||
|
||||
SkyRenderer(Ogre::SceneManager *owner)
|
||||
: mSceneManager(owner)
|
||||
, mSceneNode(0)
|
||||
, mEnabled(false)
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~SkyRenderer()
|
||||
{
|
||||
setEnabled(false);
|
||||
if (mSceneNode)
|
||||
mSceneManager->destroySceneNode(mSceneNode);
|
||||
}
|
||||
|
||||
Ogre::SceneNode *mSceneNode;
|
||||
bool mEnabled;
|
||||
|
||||
void setEnabled(bool enable)
|
||||
{
|
||||
if (enable == mEnabled)
|
||||
return;
|
||||
mEnabled = enable;
|
||||
enable ? mSceneManager->addListener(this) :
|
||||
mSceneManager->removeListener(this);
|
||||
}
|
||||
void
|
||||
postFindVisibleObjects(Ogre::SceneManager *source,
|
||||
Ogre::SceneManager::IlluminationRenderStage irs,
|
||||
Ogre::Viewport *vp) override
|
||||
{
|
||||
// Queue skies, if viewport seems it
|
||||
if (!vp->getSkiesEnabled() ||
|
||||
irs == Ogre::SceneManager::IRS_RENDER_TO_TEXTURE)
|
||||
return;
|
||||
|
||||
if (!mEnabled || !mSceneNode)
|
||||
return;
|
||||
|
||||
// Update nodes
|
||||
// Translate the box by the camera position (constant distance)
|
||||
mSceneNode->setPosition(vp->getCamera()->getDerivedPosition());
|
||||
_updateRenderQueue(source->getRenderQueue());
|
||||
}
|
||||
};
|
||||
class SkyBoxRenderer : public SkyRenderer {
|
||||
std::unique_ptr<Ogre::ManualObject> mSkyBoxObj;
|
||||
|
||||
Ogre::Quaternion mSkyBoxOrientation;
|
||||
void _updateRenderQueue(Ogre::RenderQueue *queue) override
|
||||
{
|
||||
if (mSkyBoxObj->isVisible()) {
|
||||
mSkyBoxObj->_updateRenderQueue(queue);
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
SkyBoxRenderer(Ogre::SceneManager *owner)
|
||||
: SkyRenderer(owner)
|
||||
{
|
||||
}
|
||||
Ogre::SceneManager::SkyBoxGenParameters mSkyBoxGenParameters;
|
||||
void create(const Ogre::String &materialName, Ogre::Real distance,
|
||||
uint8_t renderQueue, const Ogre::Quaternion &orientation,
|
||||
const Ogre::String &groupName)
|
||||
{
|
||||
Ogre::MaterialPtr m =
|
||||
Ogre::MaterialManager::getSingleton().getByName(
|
||||
materialName, groupName);
|
||||
OgreAssert(m, "Sky box material '" + materialName +
|
||||
"' not found.");
|
||||
// Ensure loaded
|
||||
m->load();
|
||||
|
||||
bool valid = m->getBestTechnique() &&
|
||||
m->getBestTechnique()->getNumPasses();
|
||||
#if 0
|
||||
if (valid) {
|
||||
Pass *pass = m->getBestTechnique()->getPass(0);
|
||||
valid = valid && pass->getNumTextureUnitStates() &&
|
||||
pass->getTextureUnitState(0)->getTextureType() ==
|
||||
TEX_TYPE_CUBE_MAP;
|
||||
}
|
||||
|
||||
if (!valid) {
|
||||
LogManager::getSingleton().logWarning(
|
||||
"skybox material " + materialName +
|
||||
" is not supported, defaulting");
|
||||
m = MaterialManager::getSingleton().getDefaultSettings();
|
||||
}
|
||||
#endif
|
||||
OgreAssert(valid, "Bad material" + materialName);
|
||||
|
||||
// Create node
|
||||
mSceneNode = mSceneManager->createSceneNode();
|
||||
|
||||
// Create object
|
||||
mSkyBoxObj = std::make_unique<Ogre::ManualObject>("SkyBox");
|
||||
mSkyBoxObj->setCastShadows(false);
|
||||
mSceneNode->attachObject(mSkyBoxObj.get());
|
||||
|
||||
mSkyBoxObj->setRenderQueueGroup(renderQueue);
|
||||
mSkyBoxObj->begin(materialName,
|
||||
Ogre::RenderOperation::OT_TRIANGLE_STRIP,
|
||||
groupName);
|
||||
|
||||
// rendering cube, only using 14 vertices
|
||||
const Ogre::Vector3 cube_strip[14] = {
|
||||
{ -1.f, 1.f, 1.f }, // Front-top-left
|
||||
{ 1.f, 1.f, 1.f }, // Front-top-right
|
||||
{ -1.f, -1.f, 1.f }, // Front-bottom-left
|
||||
{ 1.f, -1.f, 1.f }, // Front-bottom-right
|
||||
{ 1.f, -1.f, -1.f }, // Back-bottom-right
|
||||
{ 1.f, 1.f, 1.f }, // Front-top-right
|
||||
{ 1.f, 1.f, -1.f }, // Back-top-right
|
||||
{ -1.f, 1.f, 1.f }, // Front-top-left
|
||||
{ -1.f, 1.f, -1.f }, // Back-top-left
|
||||
{ -1.f, -1.f, 1.f }, // Front-bottom-left
|
||||
{ -1.f, -1.f, -1.f }, // Back-bottom-left
|
||||
{ 1.f, -1.f, -1.f }, // Back-bottom-right
|
||||
{ -1.f, 1.f, -1.f }, // Back-top-left
|
||||
{ 1.f, 1.f, -1.f } // Back-top-right
|
||||
};
|
||||
|
||||
for (const auto &vtx : cube_strip) {
|
||||
mSkyBoxObj->position(orientation * (vtx * distance));
|
||||
// Note UVs mirrored front/back
|
||||
mSkyBoxObj->textureCoord(vtx.normalisedCopy() *
|
||||
Ogre::Vector3(1, 1, -1));
|
||||
}
|
||||
|
||||
mSkyBoxObj->end();
|
||||
mSkyBoxGenParameters.skyBoxDistance = distance;
|
||||
}
|
||||
};
|
||||
|
||||
class EditUI : public Ogre::RenderTargetListener {
|
||||
App *m_app;
|
||||
Ogre::SceneManager *mScnMgr;
|
||||
Ogre::ImGuiOverlay *mGuiOverlay;
|
||||
OgreBites::ImGuiInputListener *mGuiListener;
|
||||
void
|
||||
preViewportUpdate(const Ogre::RenderTargetViewportEvent &evt) override
|
||||
{
|
||||
preview(evt);
|
||||
}
|
||||
|
||||
public:
|
||||
EditUI(App *app)
|
||||
: Ogre::RenderTargetListener()
|
||||
, m_app(app)
|
||||
{
|
||||
}
|
||||
|
||||
void position_editor(Ogre::SceneNode *node)
|
||||
{
|
||||
Ogre::Vector3 position = node->getPosition();
|
||||
float v[3] = { position.x, position.y, position.z };
|
||||
ImGui::InputFloat3("position", v);
|
||||
position.x = v[0];
|
||||
position.y = v[1];
|
||||
position.z = v[2];
|
||||
node->setPosition(position);
|
||||
}
|
||||
void orientation_editor(Ogre::SceneNode *node)
|
||||
{
|
||||
Ogre::Quaternion q = node->getOrientation();
|
||||
float yaw = Ogre::Radian(q.getYaw()).valueDegrees();
|
||||
float pitch = Ogre::Radian(q.getPitch()).valueDegrees();
|
||||
float roll = Ogre::Radian(q.getRoll()).valueDegrees();
|
||||
bool m1 = ImGui::InputFloat("yaw", &yaw);
|
||||
bool m2 = ImGui::InputFloat("pitch", &pitch);
|
||||
bool m3 = ImGui::InputFloat("roll", &roll);
|
||||
if (m1 || m2 || m3) {
|
||||
Ogre::Quaternion q1(Ogre::Radian(Ogre::Degree(yaw)),
|
||||
Ogre::Vector3::UNIT_Y);
|
||||
Ogre::Quaternion q2(Ogre::Degree(pitch),
|
||||
Ogre::Vector3::UNIT_X);
|
||||
Ogre::Quaternion q3(Ogre::Degree(roll),
|
||||
Ogre::Vector3::UNIT_Z);
|
||||
node->setOrientation(q1 * q2 * q3);
|
||||
}
|
||||
}
|
||||
void attachments_editor(Ogre::SceneNode *node)
|
||||
{
|
||||
const Ogre::SceneNode::ObjectMap &pmap =
|
||||
node->getAttachedObjects();
|
||||
int i;
|
||||
for (i = 0; i < pmap.size(); i++) {
|
||||
const Ogre::MovableObject *mobj = pmap[i];
|
||||
const Ogre::String &pname = mobj->getName();
|
||||
ImGui::Text("Name: %s", pname.c_str());
|
||||
}
|
||||
}
|
||||
std::vector<Ogre::String> glb_names;
|
||||
void init_glb_list()
|
||||
{
|
||||
int i;
|
||||
|
||||
const std::vector<Ogre::String> &groups =
|
||||
Ogre::ResourceGroupManager::getSingleton()
|
||||
.getResourceGroups();
|
||||
for (i = 0; i < groups.size(); i++) {
|
||||
std::vector<Ogre::String> names =
|
||||
*Ogre::ResourceGroupManager::getSingleton()
|
||||
.findResourceNames(groups[i], "*.glb");
|
||||
glb_names.insert(glb_names.end(), names.begin(),
|
||||
names.end());
|
||||
}
|
||||
}
|
||||
void buildings_editor();
|
||||
void buttons_panel();
|
||||
void preview(const Ogre::RenderTargetViewportEvent &evt);
|
||||
float panel_width;
|
||||
void initGui();
|
||||
};
|
||||
class App : public OgreBites::ApplicationContext {
|
||||
std::unique_ptr<Ogre::Bullet::DynamicsWorld> mDynWorld;
|
||||
std::unique_ptr<Ogre::Bullet::DebugDrawer> mDbgDraw;
|
||||
Ogre::SceneNode *mCameraNode, *mCameraPivot, *mCameraGoal;
|
||||
Ogre::Camera *mCamera;
|
||||
Ogre::Real mPivotPitch;
|
||||
Ogre::SceneManager *mScnMgr;
|
||||
OgreBites::InputListenerChain mInput;
|
||||
Ogre::Viewport *mViewport;
|
||||
EditUI m_edit_ui;
|
||||
TerrainSetup m_terrain;
|
||||
Ogre::Light *mSun;
|
||||
SkyBoxRenderer *sky;
|
||||
Water m_water;
|
||||
// OgreBites::TrayManager *mTrayMgr;
|
||||
class KeyboardListener : public OgreBites::InputListener,
|
||||
public Ogre::FrameListener {
|
||||
App *mApp;
|
||||
|
||||
public:
|
||||
Ogre::Vector3 motion;
|
||||
bool gui_active;
|
||||
Ogre::Timer fps_timer;
|
||||
bool fast;
|
||||
KeyboardListener(App *app)
|
||||
: OgreBites::InputListener()
|
||||
, Ogre::FrameListener()
|
||||
, mApp(app)
|
||||
, gui_active(false)
|
||||
, fast(false)
|
||||
{
|
||||
}
|
||||
bool keyPressed(const OgreBites::KeyboardEvent &evt) override
|
||||
{
|
||||
if (gui_active)
|
||||
return false;
|
||||
if (evt.keysym.sym == OgreBites::SDLK_ESCAPE) {
|
||||
gui_active = true;
|
||||
// std::cout << "Escape!\n";
|
||||
// Ogre::Root::getSingleton().queueEndRendering();
|
||||
mApp->setWindowGrab(false);
|
||||
}
|
||||
if (evt.keysym.sym == OgreBites::SDLK_SPACE)
|
||||
mApp->dump_water();
|
||||
if (evt.keysym.sym == 'w')
|
||||
motion.z = -1.0f;
|
||||
if (evt.keysym.sym == 's')
|
||||
motion.z = 1.0f;
|
||||
if (evt.keysym.sym == 'a')
|
||||
motion.x = -1.0f;
|
||||
if (evt.keysym.sym == 'd')
|
||||
motion.x = 1.0f;
|
||||
if (evt.keysym.sym == OgreBites::SDLK_LSHIFT)
|
||||
fast = true;
|
||||
// std::cout << "motion: " << motion << "\n";
|
||||
return true;
|
||||
}
|
||||
bool keyReleased(const OgreBites::KeyboardEvent &evt) override
|
||||
{
|
||||
if (gui_active)
|
||||
return false;
|
||||
if (evt.keysym.sym == 'w' && motion.z < 0.0f)
|
||||
motion.z = 0.0f;
|
||||
if (evt.keysym.sym == 's' && motion.z > 0.0f)
|
||||
motion.z = 0.0f;
|
||||
if (evt.keysym.sym == 'a' && motion.x < 0.0f)
|
||||
motion.x = 0.0f;
|
||||
if (evt.keysym.sym == 'd' && motion.x > 0.0f)
|
||||
motion.x = 0.0f;
|
||||
if (evt.keysym.sym == OgreBites::SDLK_LSHIFT)
|
||||
fast = false;
|
||||
return true;
|
||||
}
|
||||
bool mouseMoved(const OgreBites::MouseMotionEvent &evt)
|
||||
{
|
||||
if (gui_active)
|
||||
return false;
|
||||
// update camera goal based on mouse movement
|
||||
mApp->updateCameraGoal(-0.18f * evt.xrel,
|
||||
-0.12f * evt.yrel, 0);
|
||||
return true;
|
||||
}
|
||||
bool mouseWheelRolled(const OgreBites::MouseWheelEvent &evt)
|
||||
{
|
||||
if (gui_active)
|
||||
return false;
|
||||
// update camera goal based on mouse movement
|
||||
mApp->updateCameraGoal(0, 0, -0.15f * evt.y);
|
||||
return true;
|
||||
}
|
||||
void update(float delta)
|
||||
{
|
||||
return;
|
||||
// float fade = (1.0f - delta) * 0.98f;
|
||||
// motion *= fade;
|
||||
}
|
||||
void frameRendered(const Ogre::FrameEvent &evt) override
|
||||
{
|
||||
if (fps_timer.getMilliseconds() > 1000.0f) {
|
||||
std::cout << "FPS: "
|
||||
<< mApp->getRenderWindow()
|
||||
->getStatistics()
|
||||
.lastFPS
|
||||
<< " ";
|
||||
std::cout << "Draw calls: "
|
||||
<< mApp->getRenderWindow()
|
||||
->getStatistics()
|
||||
.batchCount
|
||||
<< " ";
|
||||
fps_timer.reset();
|
||||
std::cout << "Drops: "
|
||||
<< mApp->getRenderWindow()
|
||||
->getStatistics()
|
||||
.vBlankMissCount
|
||||
<< "\n";
|
||||
fps_timer.reset();
|
||||
}
|
||||
update(evt.timeSinceLastFrame);
|
||||
if (!gui_active) {
|
||||
mApp->updateMotion(evt.timeSinceLastFrame);
|
||||
mApp->updateCamera(evt.timeSinceLastFrame);
|
||||
mApp->updateSun(evt.timeSinceLastFrame);
|
||||
mApp->updateTerrain(evt.timeSinceLastFrame);
|
||||
mApp->updateWater(evt.timeSinceLastFrame);
|
||||
}
|
||||
}
|
||||
};
|
||||
KeyboardListener mKbd;
|
||||
|
||||
public:
|
||||
App()
|
||||
: OgreBites::ApplicationContext("GuiTest")
|
||||
, mKbd(this)
|
||||
, m_edit_ui(this)
|
||||
, mDynWorld(new Ogre::Bullet::DynamicsWorld(
|
||||
Ogre::Vector3(0, -9.8, 0)))
|
||||
, m_terrain(mDynWorld->getBtWorld())
|
||||
{
|
||||
}
|
||||
virtual ~App()
|
||||
{
|
||||
}
|
||||
void setup()
|
||||
{
|
||||
OgreBites::ApplicationContext::setup();
|
||||
Ogre::Root *root = getRoot();
|
||||
Ogre::SceneManager *scnMgr = root->createSceneManager();
|
||||
mScnMgr = scnMgr;
|
||||
Ogre::OverlaySystem *pOverlaySystem = getOverlaySystem();
|
||||
mScnMgr->addRenderQueueListener(pOverlaySystem);
|
||||
// mTrayMgr = new OgreBites::TrayManager("AppTrays",
|
||||
// getRenderWindow());
|
||||
mDbgDraw.reset(new Ogre::Bullet::DebugDrawer(
|
||||
mScnMgr->getRootSceneNode(), mDynWorld->getBtWorld()));
|
||||
}
|
||||
void locateResources() override
|
||||
{
|
||||
OgreBites::ApplicationContext::locateResources();
|
||||
}
|
||||
void loadResources() override
|
||||
{
|
||||
}
|
||||
void dump_water()
|
||||
{
|
||||
m_water.dump_textures();
|
||||
}
|
||||
|
||||
void initCamera()
|
||||
{
|
||||
mCameraNode = mScnMgr->getRootSceneNode()->createChildSceneNode(
|
||||
"CameraNode");
|
||||
mCameraNode->setPosition(0, 2, 3);
|
||||
mCameraNode->lookAt(Ogre::Vector3(0, 1, -1),
|
||||
Ogre::Node::TS_PARENT);
|
||||
|
||||
// create the camera
|
||||
mCamera = mScnMgr->createCamera("fps_camera");
|
||||
mCamera->setNearClipDistance(0.05f);
|
||||
mCamera->setAutoAspectRatio(true);
|
||||
mCameraNode->attachObject(mCamera);
|
||||
|
||||
// and tell it to render into the main window
|
||||
mViewport = getRenderWindow()->addViewport(mCamera);
|
||||
mCameraPivot =
|
||||
mScnMgr->getRootSceneNode()->createChildSceneNode(
|
||||
"FPSCameraPivot");
|
||||
mCameraGoal = mCameraPivot->createChildSceneNode(
|
||||
"FPSCameraGoal", Ogre::Vector3(0, 2, 3));
|
||||
mCameraNode->setPosition(mCameraPivot->getPosition() +
|
||||
mCameraGoal->getPosition());
|
||||
mCameraPivot->setFixedYawAxis(true);
|
||||
mCameraGoal->setFixedYawAxis(true);
|
||||
mCameraNode->setFixedYawAxis(true);
|
||||
// our model is quite small, so reduce the clipping planes
|
||||
mCamera->setNearClipDistance(0.1f);
|
||||
mCamera->setFarClipDistance(800);
|
||||
mPivotPitch = 0;
|
||||
}
|
||||
void configure()
|
||||
{
|
||||
std::cout << "Startup" << "\n";
|
||||
initApp();
|
||||
std::cout << "Set up RTSS" << "\n";
|
||||
Ogre::Root *root = getRoot();
|
||||
Ogre::SceneManager *scnMgr = getSceneManager();
|
||||
|
||||
// register our scene with the RTSS
|
||||
Ogre::RTShader::ShaderGenerator *shadergen =
|
||||
Ogre::RTShader::ShaderGenerator::getSingletonPtr();
|
||||
shadergen->addSceneManager(scnMgr);
|
||||
setWindowGrab(true);
|
||||
std::cout << "Init camera" << "\n";
|
||||
initCamera();
|
||||
std::cout << "Set up water" << "\n";
|
||||
m_water.createWater(getRenderWindow(), mCamera);
|
||||
std::cout << "Set up cursor" << "\n";
|
||||
Ogre::ResourceGroupManager::getSingleton().initialiseAllResourceGroups();
|
||||
// OgreBites::ApplicationContext::loadResources();
|
||||
setupCursor();
|
||||
std::cout << "Create content" << "\n";
|
||||
createContent();
|
||||
std::cout << "Setup terrain" << "\n";
|
||||
setupTerrain();
|
||||
m_water.init();
|
||||
}
|
||||
void setupCursor()
|
||||
{
|
||||
|
||||
// mKeyDirection = Ogre::Vector3::ZERO;
|
||||
// mVerticalVelocity = 0;
|
||||
Ogre::ManualObject *mobj =
|
||||
mScnMgr->createManualObject("cursorGen");
|
||||
|
||||
#if 0
|
||||
Ogre::MaterialPtr mat =
|
||||
Ogre::static_pointer_cast<Ogre::Material>(
|
||||
Ogre::MaterialManager::getSingleton()
|
||||
.createOrRetrieve("Debug/Red2",
|
||||
"General")
|
||||
.first);
|
||||
mat->removeAllTechniques();
|
||||
Ogre::Technique *tech = mat->createTechnique();
|
||||
tech->setDiffuse(Ogre::ColourValue(1, 0, 0, 1));
|
||||
tech->setName("Debug/S");
|
||||
tech->setDepthCheckEnabled(false);
|
||||
tech->setLightingEnabled(false);
|
||||
mobj->begin(mat, Ogre::RenderOperation::OT_LINE_LIST);
|
||||
#endif
|
||||
mobj->begin("Debug/Red", Ogre::RenderOperation::OT_LINE_LIST);
|
||||
mobj->position(0, 0, 0);
|
||||
mobj->colour(Ogre::ColourValue(1, 0, 0));
|
||||
mobj->position(0, 2, 0);
|
||||
mobj->colour(Ogre::ColourValue(1, 0, 0));
|
||||
mobj->position(-1, 1, 0);
|
||||
mobj->colour(Ogre::ColourValue(1, 0, 0));
|
||||
mobj->position(1, 1, 0);
|
||||
mobj->colour(Ogre::ColourValue(1, 0, 0));
|
||||
mobj->index(0);
|
||||
mobj->index(1);
|
||||
mobj->index(2);
|
||||
mobj->index(3);
|
||||
mobj->end();
|
||||
mCameraPivot->attachObject(mobj);
|
||||
}
|
||||
Ogre::SceneManager *getSceneManager()
|
||||
{
|
||||
return mScnMgr;
|
||||
}
|
||||
void updateMotion(float delta)
|
||||
{
|
||||
if (delta == 0.0f)
|
||||
return;
|
||||
Ogre::Vector3 move(mCameraNode->getOrientation().zAxis() *
|
||||
mKbd.motion.z);
|
||||
move += Ogre::Vector3(mCameraNode->getOrientation().xAxis() *
|
||||
mKbd.motion.x);
|
||||
move.y = 0.0f;
|
||||
float speed = 15.0f;
|
||||
if (mKbd.fast)
|
||||
speed = 40.0f;
|
||||
Ogre::Vector3 opos = mCameraPivot->getPosition();
|
||||
Ogre::Vector3 pos =
|
||||
mCameraPivot->getPosition() + move * speed * delta;
|
||||
float y = m_terrain.get_height(pos);
|
||||
if (y < 0)
|
||||
y = 0.0f;
|
||||
pos.y = y;
|
||||
|
||||
mCameraPivot->translate(pos - opos);
|
||||
// mKbd.motion = Ogre::Vector3(0, 0, 0);
|
||||
// if (move.squaredLength() > 0)
|
||||
// std::cout << move << "\n";
|
||||
}
|
||||
void updateCamera(Ogre::Real delta)
|
||||
{
|
||||
if (delta == 0.0f)
|
||||
return;
|
||||
// place the camera pivot roughly at the character's shoulder
|
||||
// mCameraPivot->setPosition(mBodyNode->getPosition() +
|
||||
// Ogre::Vector3::UNIT_Y * CAM_HEIGHT);
|
||||
// move the camera smoothly to the goal
|
||||
Ogre::Vector3 goalOffset = mCameraGoal->_getDerivedPosition() -
|
||||
mCameraNode->getPosition();
|
||||
float l = goalOffset.squaredLength();
|
||||
Ogre::Vector3 v = goalOffset * 10.0 * delta;
|
||||
if (v.squaredLength() > l * 0.5f - delta)
|
||||
v = goalOffset * delta;
|
||||
mCameraNode->translate(v);
|
||||
// mCameraNode->translate(goalOffset);
|
||||
// always look at the pivot
|
||||
mCameraNode->lookAt(mCameraPivot->_getDerivedPosition(),
|
||||
Ogre::Node::TS_PARENT);
|
||||
}
|
||||
void updateCameraGoal(Ogre::Real deltaYaw, Ogre::Real deltaPitch,
|
||||
Ogre::Real deltaZoom)
|
||||
{
|
||||
mCameraPivot->yaw(Ogre::Degree(deltaYaw),
|
||||
Ogre::Node::TS_PARENT);
|
||||
if (!(mPivotPitch + deltaPitch > 25 && deltaPitch > 0) &&
|
||||
!(mPivotPitch + deltaPitch < -60 && deltaPitch < 0)) {
|
||||
mCameraPivot->pitch(Ogre::Degree(deltaPitch),
|
||||
Ogre::Node::TS_LOCAL);
|
||||
mPivotPitch += deltaPitch;
|
||||
}
|
||||
Ogre::Real dist = mCameraGoal->_getDerivedPosition().distance(
|
||||
mCameraPivot->_getDerivedPosition());
|
||||
Ogre::Real distChange = deltaZoom * dist * 0.5f;
|
||||
if (distChange > 0 && dist + distChange > 30)
|
||||
distChange *= 0.3f;
|
||||
if (distChange < 0 && dist + distChange < 5)
|
||||
distChange *= 0.2f;
|
||||
|
||||
// bound the zoom
|
||||
if (!(dist + distChange < 3 && distChange < 0) &&
|
||||
!(dist + distChange > 60 && distChange > 0))
|
||||
mCameraGoal->translate(0, 0, distChange,
|
||||
Ogre::Node::TS_LOCAL);
|
||||
Ogre::Vector3 mh = mCameraGoal->_getDerivedPosition();
|
||||
float h = m_terrain.get_height(mh);
|
||||
if (h + 10 > mh.y)
|
||||
mCameraGoal->translate(0, 10.0f * deltaZoom, distChange,
|
||||
Ogre::Node::TS_LOCAL);
|
||||
}
|
||||
Ogre::SceneNode *mSunGoal;
|
||||
Ogre::SceneNode *mSunNode;
|
||||
Ogre::SceneNode *mSunTarget;
|
||||
Ogre::Timer mSunUpdate;
|
||||
void createSun()
|
||||
{
|
||||
Ogre::Light *light = mScnMgr->createLight("Sun");
|
||||
mSunNode = mScnMgr->getRootSceneNode()->createChildSceneNode(
|
||||
"SunPivot");
|
||||
mSunGoal = mScnMgr->getRootSceneNode()->createChildSceneNode(
|
||||
"SunGoal");
|
||||
mSunTarget = mSunGoal->createChildSceneNode(
|
||||
"SunGoalTarget",
|
||||
Ogre::Vector3(100.0f, -400.0f, -400.0f),
|
||||
Ogre::Quaternion::IDENTITY);
|
||||
// mSunNode->setAutoTracking(true, sun_target);
|
||||
// lightNode->setPosition(0, 10, 15);
|
||||
mSunNode->attachObject(light);
|
||||
light->setType(Ogre::Light::LT_DIRECTIONAL);
|
||||
light->setDiffuseColour(Ogre::ColourValue::White);
|
||||
light->setSpecularColour(Ogre::ColourValue(0.4, 0.4, 0.4));
|
||||
mSunNode->setDirection(Ogre::Vector3(100.0f, -400.0f, -400.f));
|
||||
mSun = light;
|
||||
}
|
||||
void updateSun(float delta)
|
||||
{
|
||||
static const float sun_speed = 1.0f;
|
||||
float uangle = M_PI * 2.0f / 24.0f / 60.0f;
|
||||
mSunNode->pitch(Ogre::Radian(uangle) * sun_speed * delta);
|
||||
if (mSunUpdate.getMilliseconds() > 1000) {
|
||||
Ogre::TerrainGlobalOptions::getSingleton()
|
||||
.setCompositeMapAmbient(
|
||||
mScnMgr->getAmbientLight());
|
||||
Ogre::TerrainGlobalOptions::getSingleton()
|
||||
.setCompositeMapDiffuse(
|
||||
mSun->getDiffuseColour());
|
||||
Ogre::TerrainGlobalOptions::getSingleton()
|
||||
.setLightMapDirection(
|
||||
mSun->getDerivedDirection());
|
||||
std::cout << "sun pitch: "
|
||||
<< mSunNode->getOrientation().getPitch()
|
||||
<< "\n";
|
||||
mSunUpdate.reset();
|
||||
}
|
||||
if (mSunNode->getOrientation().getPitch().valueRadians() > 0)
|
||||
mScnMgr->setAmbientLight(
|
||||
Ogre::ColourValue(0.1f, 0.1f, 0.4f, 1.0f));
|
||||
else
|
||||
mScnMgr->setAmbientLight(
|
||||
Ogre::ColourValue(0.2f, 0.2f, 0.2f, 1.0f));
|
||||
}
|
||||
Ogre::Timer mTerrainUpd;
|
||||
void updateTerrain(float delta)
|
||||
{
|
||||
// mDbgDraw->update();
|
||||
#if 0
|
||||
if (mTerrainUpd.getMilliseconds() > 1000) {
|
||||
m_terrain.create_colliders();
|
||||
mTerrainUpd.reset();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
void updateWater(float delta)
|
||||
{
|
||||
m_water.updateWater(delta);
|
||||
}
|
||||
void createContent()
|
||||
{
|
||||
int i;
|
||||
m_edit_ui.init_glb_list();
|
||||
m_edit_ui.initGui();
|
||||
createSun();
|
||||
mInput = OgreBites::InputListenerChain(
|
||||
{ getImGuiInputListener(), &mKbd });
|
||||
addInputListener(&mInput);
|
||||
getRoot()->addFrameListener(&mKbd);
|
||||
// mTrayMgr->showCursor();
|
||||
|
||||
// OgreBites::TrayManager *mTrayMgr = new OgreBites::TrayManager(
|
||||
// "InterfaceName", getRenderWindow());
|
||||
// mScnMgr->setSkyBox(true, "Skybox/Dynamic", 490);
|
||||
// /* mCamera->getCameraToViewportRay(left, top); */
|
||||
#if 1
|
||||
sky = new SkyBoxRenderer(getSceneManager());
|
||||
bool drawFirst = true;
|
||||
uint8_t renderQueue = drawFirst ?
|
||||
Ogre::RENDER_QUEUE_SKIES_EARLY :
|
||||
Ogre::RENDER_QUEUE_SKIES_LATE;
|
||||
sky->create("Skybox/Dynamic", 450, renderQueue,
|
||||
Ogre::Quaternion::IDENTITY,
|
||||
Ogre::ResourceGroupManager::
|
||||
AUTODETECT_RESOURCE_GROUP_NAME);
|
||||
sky->setEnabled(true);
|
||||
|
||||
Ogre::MaterialPtr m =
|
||||
Ogre::MaterialManager::getSingleton().getByName(
|
||||
"Skybox/Dynamic", "General");
|
||||
OgreAssert(m, "Sky box material not found.");
|
||||
m->load();
|
||||
#endif
|
||||
}
|
||||
void create_entity_node(const Ogre::String &name, int key)
|
||||
{
|
||||
Ogre::Entity *ent = mScnMgr->createEntity(name);
|
||||
Ogre::SceneNode *pnode =
|
||||
mScnMgr->getRootSceneNode()->createChildSceneNode(
|
||||
"ent:" + name +
|
||||
Ogre::StringConverter::toString(key),
|
||||
mCameraPivot->getPosition(),
|
||||
mCameraPivot->getOrientation());
|
||||
pnode->attachObject(ent);
|
||||
Ogre::Quaternion q = pnode->getOrientation();
|
||||
Ogre::Radian yaw = q.getYaw();
|
||||
Ogre::Quaternion nq(yaw, Ogre::Vector3(0, 1, 0));
|
||||
pnode->setOrientation(nq);
|
||||
mKbd.gui_active = false;
|
||||
setWindowGrab(true);
|
||||
}
|
||||
bool get_gui_active()
|
||||
{
|
||||
return mKbd.gui_active;
|
||||
}
|
||||
void set_gui_active(bool active)
|
||||
{
|
||||
mKbd.gui_active = active;
|
||||
}
|
||||
Ogre::Camera *getCamera()
|
||||
{
|
||||
return mCamera;
|
||||
}
|
||||
void setupTerrain()
|
||||
{
|
||||
m_terrain.setupTerrain(mCamera, mSun, mDynWorld.get(),
|
||||
mDbgDraw.get());
|
||||
}
|
||||
};
|
||||
|
||||
void EditUI::buildings_editor()
|
||||
{
|
||||
int i;
|
||||
ImVec2 size = ImGui::GetMainViewport()->Size;
|
||||
float window_width = size.x * 0.2f;
|
||||
if (window_width > panel_width)
|
||||
window_width = panel_width;
|
||||
float window_height = size.y * 0.5 - 20;
|
||||
ImGui::SetNextWindowPos(ImVec2(0, 0), ImGuiCond_Always);
|
||||
ImGui::SetNextWindowSize(ImVec2(window_width, window_height),
|
||||
ImGuiCond_Always);
|
||||
ImGui::Begin("Droppings...");
|
||||
for (i = 0; i < glb_names.size(); i++) {
|
||||
Ogre::String id_button = "Create entity: " + glb_names[i] +
|
||||
"##ent:" + glb_names[i];
|
||||
if (ImGui::Button(id_button.c_str())) {
|
||||
m_app->create_entity_node(glb_names[i], i);
|
||||
}
|
||||
}
|
||||
ImGui::End();
|
||||
}
|
||||
void EditUI::buttons_panel()
|
||||
{
|
||||
ImVec2 size = ImGui::GetMainViewport()->Size;
|
||||
float window_width = size.x * 0.2f;
|
||||
if (window_width > panel_width)
|
||||
window_width = panel_width;
|
||||
float window_height = size.y * 0.5f - 20;
|
||||
ImGui::SetNextWindowPos(ImVec2(0, size.y * 0.5f + 20),
|
||||
ImGuiCond_Always);
|
||||
ImGui::SetNextWindowSize(ImVec2(window_width, window_height),
|
||||
ImGuiCond_Always);
|
||||
ImGui::Begin("Dumb and Stupid");
|
||||
if (!m_app->get_gui_active())
|
||||
m_app->setWindowGrab(true);
|
||||
if (ImGui::Button("Shitty Quit button"))
|
||||
Ogre::Root::getSingleton().queueEndRendering();
|
||||
if (ImGui::Button("Chick-chick")) {
|
||||
m_app->set_gui_active(false);
|
||||
m_app->setWindowGrab(true);
|
||||
}
|
||||
ImGui::Text("We do stoopid...");
|
||||
ImGui::End();
|
||||
}
|
||||
void EditUI::preview(const Ogre::RenderTargetViewportEvent &evt)
|
||||
{
|
||||
int i;
|
||||
Ogre::ImGuiOverlay::NewFrame();
|
||||
if (m_app->get_gui_active()) {
|
||||
buttons_panel();
|
||||
buildings_editor();
|
||||
ImVec2 size = ImGui::GetMainViewport()->Size;
|
||||
float window_width = size.x * 0.2f;
|
||||
if (window_width > panel_width)
|
||||
window_width = panel_width;
|
||||
float window_height = size.y * 0.5f - 20;
|
||||
ImGui::SetNextWindowPos(ImVec2(size.x - window_width,
|
||||
size.y * 0.5f + 20),
|
||||
ImGuiCond_Always);
|
||||
ImGui::SetNextWindowSize(ImVec2(window_width, window_height),
|
||||
ImGuiCond_Always);
|
||||
// ImGui::Begin("Dumb and Stupid", &mKbd.gui_active);
|
||||
ImGui::Begin("Panel...");
|
||||
std::deque<Ogre::SceneNode *> tree_input_queue,
|
||||
tree_output_queue;
|
||||
std::vector<Ogre::SceneNode *> tree_list;
|
||||
tree_input_queue.push_back(mScnMgr->getRootSceneNode());
|
||||
tree_input_queue.push_back(nullptr);
|
||||
std::set<Ogre::SceneNode *> visited;
|
||||
while (true) {
|
||||
int new_nodes_count = 0;
|
||||
while (!tree_input_queue.empty()) {
|
||||
int child;
|
||||
Ogre::SceneNode *item =
|
||||
tree_input_queue.front();
|
||||
tree_input_queue.pop_front();
|
||||
if (item && visited.find(item) ==
|
||||
visited.end()) { // new node
|
||||
new_nodes_count++;
|
||||
tree_output_queue.push_back(item);
|
||||
visited.insert(item);
|
||||
const Ogre::Node::ChildNodeMap
|
||||
&children = item->getChildren();
|
||||
for (child = 0; child < children.size();
|
||||
child++) {
|
||||
tree_output_queue.push_back(
|
||||
static_cast<Ogre::SceneNode
|
||||
*>(
|
||||
children[child]));
|
||||
tree_output_queue.push_back(
|
||||
nullptr);
|
||||
}
|
||||
} else
|
||||
tree_output_queue.push_back(item);
|
||||
}
|
||||
if (new_nodes_count == 0)
|
||||
break;
|
||||
tree_input_queue = tree_output_queue;
|
||||
tree_output_queue.clear();
|
||||
}
|
||||
tree_list.insert(tree_list.begin(), tree_output_queue.begin(),
|
||||
tree_output_queue.end());
|
||||
int count = 0;
|
||||
int depth = 0;
|
||||
std::vector<int> check_depth;
|
||||
int max_depth = 0;
|
||||
check_depth.push_back(0);
|
||||
for (count = 0; count < tree_list.size(); count++) {
|
||||
int t;
|
||||
|
||||
Ogre::SceneNode *node = tree_list[count];
|
||||
if (node && max_depth >= depth) {
|
||||
Ogre::String name = node->getName();
|
||||
if (name.length() == 0) {
|
||||
name = "Node #" +
|
||||
Ogre::StringConverter::toString(
|
||||
count);
|
||||
}
|
||||
if (ImGui::TreeNode(name.c_str())) {
|
||||
check_depth.push_back(max_depth);
|
||||
max_depth++;
|
||||
ImGui::Text(
|
||||
"%s",
|
||||
(name + "##caption").c_str());
|
||||
position_editor(node);
|
||||
ImGui::Separator();
|
||||
orientation_editor(node);
|
||||
ImGui::Separator();
|
||||
ImGui::Text("Attachments");
|
||||
attachments_editor(node);
|
||||
}
|
||||
} else if (!node && max_depth >= depth) {
|
||||
max_depth = check_depth.back();
|
||||
check_depth.pop_back();
|
||||
ImGui::TreePop();
|
||||
}
|
||||
if (tree_list[count])
|
||||
depth++;
|
||||
else
|
||||
depth--;
|
||||
}
|
||||
ImGui::Spacing();
|
||||
ImGui::End();
|
||||
}
|
||||
}
|
||||
void EditUI::initGui()
|
||||
{
|
||||
mScnMgr = m_app->getSceneManager();
|
||||
float vpScale = m_app->getDisplayDPI() / 96 *
|
||||
(float)m_app->getRenderWindow()->getWidth() / 1280;
|
||||
panel_width =
|
||||
380.0f * (float)m_app->getRenderWindow()->getWidth() / 1280;
|
||||
Ogre::OverlayManager::getSingleton().setPixelRatio(vpScale);
|
||||
mGuiOverlay = m_app->initialiseImGui();
|
||||
// float vpScale =
|
||||
// Ogre::OverlayManager::getSingleton().getPixelRatio();
|
||||
ImGui::GetIO().FontGlobalScale = std::round(vpScale);
|
||||
mGuiOverlay->setZOrder(300);
|
||||
mGuiOverlay->show();
|
||||
m_app->getRenderWindow()->addListener(this);
|
||||
}
|
||||
int main()
|
||||
{
|
||||
App ctx;
|
||||
ctx.configure();
|
||||
// ctx.runRenderingSettingsDialog();
|
||||
// get a pointer to the already created root
|
||||
// register for input events
|
||||
// KeyHandler keyHandler;
|
||||
// ctx.addInputListener(&keyHandler);
|
||||
|
||||
ctx.getRoot()->startRendering();
|
||||
ctx.setWindowGrab(false);
|
||||
ctx.closeApp();
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user