How to destroy gRenderBoxScene.

fabregot

25-01-2010 18:32:49

Hello!

First of all I would like to congratulate the MyGUI developer ;) Great Job!

I have a little question. How I destroy the gRenderBoxScene in the example Demo_RenderBox ? Because if I do : gRenderBoxScene .destroy() with gRenderBoxScene.setAutoRotation(false); the app crashes at:


#if MYGUI_DEBUG_MODE == 1
if (!RenderManager::getInstance().checkTexture(mTexture))
{
--> MYGUI_EXCEPT("texture pointer is not valid, texture name '" << mTextureName << "'");
mTexture = nullptr;
return;
}
#endif


But if with gRenderBoxScene.setAutoRotation(true); the app crashes at:

void RenderBoxScene::frameEntered(float _time)
{
if (!mLeftPressed)
{
if (mAutoRotation)
--> mNode->yaw(Ogre::Radian(Ogre::Degree(_time * mRotationSpeed)));
}
if (mAnimationState)
mAnimationState->addTime(_time);
}


I'm usign Ogre 1.7 with OGRE_THREAD_SUPPORT 1 and MyGUI 3.0.

Thanks for the help :)

my.name

25-01-2010 21:10:37

try
viewtopic.php?f=17&t=11981

fabregot

25-01-2010 21:14:45

I made this changes after and don't work :(

Try to add gRenderBoxScene .destroy() in the Demo_RenderBox and you will see it :)

Altren

25-01-2010 21:18:30

You should delete it in same thread where render is.
Looks like you deleting and trying to render it at the same time.

fabregot

25-01-2010 21:33:04

Yes, I delete it in the same thread.
I only had modified the file Demokeeper.cpp from Demo_RenderBox :

#ifdef MYGUI_OGRE_PLATFORM

gRenderBox.setCanvas(canvas);
gRenderBox.setViewport(getCamera());
gRenderBox.setBackgroundColour(MyGUI::Colour::Black);

gRenderBoxScene.setCanvas(canvas2);
gRenderBoxScene.injectObject("Robot.mesh");
gRenderBoxScene.setAutoRotation(true);
gRenderBoxScene.setMouseRotation(true);

gRenderBoxScene.destroy(); // I only add this line
#endif // MYGUI_OGRE_PLATFORM

my.name

25-01-2010 23:01:47

update RenderBoxScene.cpp or get from svn revision 2701

/*!
@file
@author Evmenov Georgiy
@date 01/2008
@module
*/

#include "RenderBoxScene.h"

namespace wraps
{

RenderBoxScene::RenderBoxScene() :
mCameraNode(nullptr),
mCamera(nullptr),
mEntity(nullptr),
mAnimationState(nullptr),
mRotationSpeed(RENDER_BOX_AUTO_ROTATION_SPEED),
mMouseRotation(false),
mLastPointerX(0),
mLeftPressed(false),
mAutoRotation(false),
mFrameAdvise(false),
mScene(nullptr),
mNode(nullptr)
{
}

RenderBoxScene::~RenderBoxScene()
{
}

void RenderBoxScene::destroy()
{
clearScene();

if (mCanvas)
{
frameAdvise(false);

mCanvas->eventMouseDrag = nullptr;
mCanvas->eventMouseButtonPressed = nullptr;
mCanvas->eventMouseButtonReleased = nullptr;
mCanvas = nullptr;

Ogre::Root* root = Ogre::Root::getSingletonPtr();
if (root && mScene)
root->destroySceneManager(mScene);
mScene = nullptr;
mNode = nullptr;
}

RenderBox::destroy();
}

void RenderBoxScene::setCanvas(MyGUI::CanvasPtr _value)
{
RenderBox::setCanvas(_value);

mCanvas->eventMouseDrag = newDelegate(this, &RenderBoxScene::notifyMouseDrag);
mCanvas->eventMouseButtonPressed = newDelegate(this, &RenderBoxScene::notifyMouseButtonPressed);
mCanvas->eventMouseButtonReleased = newDelegate(this, &RenderBoxScene::notifyMouseButtonReleased);

createScene();
}

// добавляет в сцену объект, старый удаляеться
void RenderBoxScene::injectObject(const Ogre::String& _meshName, const Ogre::Vector3 & _position, const Ogre::Quaternion & _orientation, const Ogre::Vector3 & _scale)
{
clearScene();

static size_t num = 0;
mEntity = mScene->createEntity(MyGUI::utility::toString(this, "_RenderBoxMesh_", _meshName, num++), _meshName);
Ogre::SceneNode * node = mNode->createChildSceneNode(_position, _orientation);
node->attachObject(mEntity);

updateViewport();
}

void RenderBoxScene::setAnimation(const Ogre::String& _animation)
{
if (mEntity == nullptr)
return;

try
{
mAnimationState = mEntity->getAnimationState(_animation);
mAnimationState->setEnabled(true);
mAnimationState->setLoop(true);
mAnimationState->setWeight(1);
}
catch (Ogre::ItemIdentityException&)
{
}

frameAdvise(needFrameUpdate());
}

// очищает сцену
void RenderBoxScene::clearScene()
{
setRotationAngle(Ogre::Degree(0));

if (mScene)
{
mScene->destroyAllEntities();
mNode->removeAndDestroyAllChildren();
}

mEntity = nullptr;
mAnimationState = nullptr;
}

void RenderBoxScene::setAutoRotationSpeed(int _value)
{
mRotationSpeed = _value;
}

void RenderBoxScene::setRotationAngle(const Ogre::Degree& _value)
{
if (mNode)
{
mNode->resetOrientation();
mNode->yaw(Ogre::Radian(_value));
}
}

Ogre::Degree RenderBoxScene::getRotationAngle()
{
return Ogre::Degree(mNode->getOrientation().getYaw());
}

void RenderBoxScene::setMouseRotation(bool _enable)
{
mMouseRotation = _enable;
}

void RenderBoxScene::frameEntered(float _time)
{
if (!mLeftPressed)
{
if (mAutoRotation && mNode)
mNode->yaw(Ogre::Radian(Ogre::Degree(_time * mRotationSpeed)));
}
if (mAnimationState)
mAnimationState->addTime(_time);
}

void RenderBoxScene::createScene()
{
// создаем новый сцен менеджер
mScene = Ogre::Root::getSingleton().createSceneManager(Ogre::ST_GENERIC, MyGUI::utility::toString(this, "_SceneManagerRenderBox"));

// создаем нод к которуму будем всякую дрянь атачить
mNode = mScene->getRootSceneNode()->createChildSceneNode();

mScene->setAmbientLight(Ogre::ColourValue(0.8, 0.8, 0.8));

// главный источник света
Ogre::Vector3 dir(-1, -1, 0.5);
dir.normalise();
Ogre::Light * light = mScene->createLight(MyGUI::utility::toString(this, "_LightRenderBox"));
light->setType(Ogre::Light::LT_DIRECTIONAL);
light->setDirection(dir);

std::string camera(MyGUI::utility::toString(this, "_CameraRenderBox"));
mCamera = mScene->createCamera(camera);
mCamera->setNearClipDistance(1);

mCameraNode = mScene->getRootSceneNode()->createChildSceneNode(camera);
mCameraNode->attachObject(mCamera);

if (mCanvas->getHeight() == 0)
mCamera->setAspectRatio(1);
else
mCamera->setAspectRatio( float(mCanvas->getWidth()) / float(mCanvas->getHeight()) );

setViewport(mCamera);
}

void RenderBoxScene::updateViewport()
{
// при нуле вылетает
if ((mCanvas->getWidth() <= 1) || (mCanvas->getHeight() <= 1))
return;

if ((nullptr != mEntity) && (nullptr != mCamera))
{
// не ясно, нужно ли растягивать камеру, установленную юзером
mCamera->setAspectRatio((float)mCanvas->getWidth() / (float)mCanvas->getHeight());

// вычисляем расстояние, чтобы был виден весь объект
Ogre::AxisAlignedBox box;

box.merge(mEntity->getBoundingBox().getMinimum() + mEntity->getParentSceneNode()->_getDerivedPosition());
box.merge(mEntity->getBoundingBox().getMaximum() + mEntity->getParentSceneNode()->_getDerivedPosition());

if (box.isNull()) return;

Ogre::Vector3 vec = box.getSize();

float width = sqrt(vec.x*vec.x + vec.z*vec.z); // самое длинное - диагональ (если крутить модель)
float len2 = width / mCamera->getAspectRatio();
float height = vec.y;
float len1 = height;
if (len1 < len2) len1 = len2;
len1 /= 0.86; // [sqrt(3)/2] for 60 degrees field of view
// центр объекта по вертикали + отъехать так, чтобы влезла ближняя грань BoundingBox'а + чуть вверх и еще назад для красоты
Ogre::Vector3 result = box.getCenter() + Ogre::Vector3(0, 0, vec.z/2 + len1) + Ogre::Vector3(0, height*0.1, len1*0.2);
Ogre::Vector3 look = Ogre::Vector3(0, box.getCenter().y /*+ box.getCenter().y * (1-mCurrentScale)*/, 0);

mCameraNode->setPosition(result);
mCameraNode->lookAt(look, Ogre::Node::TS_WORLD);
}
}

void RenderBoxScene::setAutoRotation(bool _auto)
{
mAutoRotation = _auto;
frameAdvise(needFrameUpdate());
}

void RenderBoxScene::requestUpdateCanvas(MyGUI::CanvasPtr _canvas, MyGUI::Canvas::Event _event)
{
RenderBox::requestUpdateCanvas(_canvas, _event);

updateViewport();
}

void RenderBoxScene::frameAdvise(bool _advise)
{
if (_advise && !mFrameAdvise && needFrameUpdate())
{
MyGUI::Gui::getInstance().eventFrameStart += MyGUI::newDelegate(this, &RenderBoxScene::frameEntered);
mFrameAdvise = true;
}
else if (!_advise && mFrameAdvise && !needFrameUpdate())
{
MyGUI::Gui::getInstance().eventFrameStart -= MyGUI::newDelegate(this, &RenderBoxScene::frameEntered);
mFrameAdvise = false;
}
}

void RenderBoxScene::notifyMouseDrag(MyGUI::WidgetPtr _sender, int _left, int _top)
{
if (mMouseRotation)
{
if (mNode)
mNode->yaw(Ogre::Radian(Ogre::Degree(_left - mLastPointerX)));
mLastPointerX = _left;
}
}

void RenderBoxScene::notifyMouseButtonPressed(MyGUI::WidgetPtr _sender, int _left, int _top, MyGUI::MouseButton _id)
{
if (_id == MyGUI::MouseButton::Left)
{
if (mMouseRotation)
{
const MyGUI::IntPoint & point = MyGUI::InputManager::getInstance().getLastLeftPressed();
mLastPointerX = point.left;
mLeftPressed = true;
}
}
}

void RenderBoxScene::notifyMouseButtonReleased(MyGUI::WidgetPtr _sender, int _left, int _top, MyGUI::MouseButton _id)
{
if (MyGUI::MouseButton::Left == _id) mLeftPressed = false;
}

} // namespace wraps