Changed: #1150 reactivated 3d view and improved behaviour

This commit is contained in:
aquiles 2010-11-22 21:21:07 +01:00
parent 0f39bf77cc
commit 17d224f762
13 changed files with 730 additions and 311 deletions

View file

@ -3,7 +3,7 @@ INCLUDE( ${QT_USE_FILE} )
FILE(GLOB GEORGES_EDITOR_SRC *.cpp *.h)
SET(GEORGES_EDITOR_HDR georges_dirtree_dialog.h georges_treeview_dialog.h main_window.h
objectviewer_dialog.h settings_dialog.h progress_dialog.h)
objectviewer_dialog.h settings_dialog.h progress_dialog.h object_viewer_widget.h)
SET(GEORGES_EDITOR_UIS settings_form.ui objectviewer_form.ui log_form.ui georges_treeview_form.ui georges_dirtree_form.ui)
SET(GEORGES_EDITOR_RCS georges_editor_qt.qrc)

View file

@ -1,6 +1,6 @@
/*
Georges Editor Qt
Copyright (C) 2010 Adrian Jaekel <aj at elane2k dot com>
Object Viewer Qt
Copyright (C) 2010 Dzmitry Kamiahin <dnk-88@tut.by>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -14,19 +14,19 @@
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "stdpch.h"
#include "entity.h"
#include <QtCore/QString>
// NeL includes
#include <nel/misc/path.h>
#include <nel/3d/u_camera.h>
#include <nel/3d/u_driver.h>
#include <nel/3d/u_text_context.h>
#include <nel/3d/u_instance.h>
#include <nel/3d/u_scene.h>
#include <nel/3d/u_material.h>
#include <nel/3d/u_landscape.h>
#include <nel/3d/u_skeleton.h>
#include <nel/3d/u_animation_set.h>
#include <nel/3d/u_animation.h>
@ -63,14 +63,38 @@ CSlotInfo& CSlotInfo::operator=(const CSlotInfo & slotInfo)
}
CEntity::CEntity(void):
_Name("<Unknown>"),
_Name("<Unknown>"), _FileNameShape(""),
_FileNameSkeleton(""), _inPlace(false), _incPos(false),
_Instance(NULL), _Skeleton(NULL),
_PlayList(NULL), _AnimationSet(NULL)
{
_CharacterScalePos = 1;
}
CEntity::~CEntity(void)
{
if (_PlayList != NULL)
{
_PlayList->resetAllChannels();
Modules::objView().getPlayListManager()->deletePlayList (_PlayList);
_PlayList = NULL;
}
if (_AnimationSet != NULL)
{
Modules::objView().getDriver()->deleteAnimationSet(_AnimationSet);
_AnimationSet = NULL;
}
if (!_Skeleton.empty())
{
_Skeleton.detachSkeletonSon(_Instance);
Modules::objView().getScene()->deleteSkeleton(_Skeleton);
_Skeleton = NULL;
}
if (!_Instance.empty())
{
Modules::objView().getScene()->deleteInstance(_Instance);
_Instance = NULL;
}
}
void CEntity::loadAnimation(std::string &fileName)
@ -93,6 +117,8 @@ void CEntity::addAnimToPlayList(std::string &name)
_PlayListAnimation.push_back(name);
_AnimationStatus.EndAnim = this->getPlayListLength();
_Instance.start();
}
void CEntity::removeAnimToPlayList(uint row)
@ -112,6 +138,11 @@ void CEntity::swapAnimToPlayList(uint row1, uint row2)
void CEntity::playbackAnim(bool play)
{
_AnimationStatus.PlayAnim = play;
if (play)
_Instance.start();
else
_Instance.freezeHRC();
}
void CEntity::reset()
@ -144,22 +175,97 @@ void CEntity::update(NL3D::TAnimationTime time)
this->resetChannel();
switch (_AnimationStatus.Mode)
{
case Mode::PlayList:
animatePlayList(time);
break;
case Mode::Mixer:
animateChannelMixer();
break;
case Mode::PlayList:
animatePlayList(time);
break;
case Mode::Mixer:
animateChannelMixer();
break;
}
}
void CEntity::resetChannel()
{
for(size_t i = 0; i < NL3D::CChannelMixer::NumAnimationSlot; i++)
for(uint i = 0; i < NL3D::CChannelMixer::NumAnimationSlot; i++)
_PlayList->setAnimation(i, UPlayList::empty);
}
void CEntity::addTransformation (CMatrix &current, UAnimation *anim, float begin, float end, UTrack *posTrack, UTrack *rotquatTrack,
UTrack *nextPosTrack, UTrack *nextRotquatTrack, bool removeLast)
{
// In place ?
if (_inPlace)
{
// Just identity
current.identity();
}
else
{
// Remove the start of the animation
CQuat rotEnd (0,0,0,1);
CVector posEnd (0,0,0);
if (rotquatTrack)
{
// Interpolate the rotation
rotquatTrack->interpolate (end, rotEnd);
}
if (posTrack)
{
// Interpolate the position
posTrack->interpolate (end, posEnd);
}
// Add the final rotation and position
CMatrix tmp;
tmp.identity ();
tmp.setRot (rotEnd);
tmp.setPos (posEnd);
// Incremental ?
if (_incPos)
current *= tmp;
else
current = tmp;
if (removeLast)
{
CQuat rotStart (0,0,0,1);
CVector posStart (0,0,0);
if (nextRotquatTrack)
{
// Interpolate the rotation
nextRotquatTrack->interpolate (begin, rotStart);
}
if (nextPosTrack)
{
// Interpolate the position
nextPosTrack->interpolate (begin, posStart);
}
// Remove the init rotation and position of the next animation
tmp.identity ();
tmp.setRot (rotStart);
tmp.setPos (posStart);
tmp.invert ();
current *= tmp;
// Normalize the mt
CVector I = current.getI ();
CVector J = current.getJ ();
I.z = 0;
J.z = 0;
J.normalize ();
CVector K = I^J;
K.normalize ();
I = J^K;
I.normalize ();
tmp.setRot (I, J, K);
tmp.setPos (current.getPos ());
current = tmp;
}
}
}
void CEntity::animatePlayList(NL3D::TAnimationTime time)
{
if (!_PlayListAnimation.empty())
@ -170,6 +276,21 @@ void CEntity::animatePlayList(NL3D::TAnimationTime time)
// Try channel AnimationSet
NL3D::UAnimation *anim = _AnimationSet->getAnimation(id);
bool there = false;
UTrack *posTrack = NULL;
UTrack *rotQuatTrack = NULL;
// Current matrix
CMatrix current;
current.identity();
// read an animation for init matrix
rotQuatTrack = anim->getTrackByName("rotquat");
posTrack = anim->getTrackByName("pos");
there = posTrack || rotQuatTrack;
// Accumul time
float startTime = 0;
float endTime = anim->getEndTime() - anim->getBeginTime();
@ -181,14 +302,29 @@ void CEntity::animatePlayList(NL3D::TAnimationTime time)
if (index < _PlayListAnimation.size())
{
id = _AnimationSet->getAnimationIdByName(_PlayListAnimation[index].c_str());
anim = _AnimationSet->getAnimation(id);
NL3D::UAnimation *newAnim = _AnimationSet->getAnimation(id);
UTrack *newPosTrack = newAnim->getTrackByName ("pos");
UTrack *newRotquatTrack = newAnim->getTrackByName ("rotquat");
// Add the transformation
addTransformation (current, anim, newAnim->getBeginTime(), anim->getEndTime(), posTrack, rotQuatTrack, newPosTrack, newRotquatTrack, true);
anim = newAnim;
posTrack = newPosTrack;
rotQuatTrack = newRotquatTrack;
// Add start time
startTime = endTime;
endTime = startTime + (anim->getEndTime() - anim->getBeginTime());
}
else
break;
{
// Add the transformation
addTransformation (current, anim, 0, anim->getEndTime(), posTrack, rotQuatTrack, NULL, NULL, false);
break;
}
}
// Time cropped ?
@ -205,6 +341,10 @@ void CEntity::animatePlayList(NL3D::TAnimationTime time)
else
{
// No
// Add the transformation
addTransformation (current, anim, 0, anim->getBeginTime() + time - startTime, posTrack, rotQuatTrack, NULL, NULL, false);
id = _AnimationSet->getAnimationIdByName(_PlayListAnimation[index].c_str());
anim = _AnimationSet->getAnimation(id);
@ -215,10 +355,31 @@ void CEntity::animatePlayList(NL3D::TAnimationTime time)
// Set the slot
_PlayList->setAnimation(0, id);
_PlayList->setTimeOrigin(0, startTime);
_PlayList->setSpeedFactor(0, 1.0f);
_PlayList->setWeightSmoothness(0, 1.0f);
_PlayList->setStartWeight(0, 1, 0);
_PlayList->setEndWeight(0, 1, 1);
_PlayList->setWrapMode(0, UPlayList::Clamp);
// Setup the pos and rot for this shape
if (there)
{
CVector pos = current.getPos();
// If a skeleton model
if(!_Skeleton.empty())
{
// scale animated pos value with the CFG scale
pos *= _CharacterScalePos;
_Skeleton.setPos(pos);
_Skeleton.setRotQuat(current.getRot());
}
else
{
_Instance.setPos(pos);
_Instance.setRotQuat(current.getRot());
}
}
}
}
@ -252,15 +413,15 @@ void CEntity::animateChannelMixer()
// Switch between wrap modes
switch (_SlotInfo[i].ClampMode)
{
case 0:
_PlayList->setWrapMode (i, UPlayList::Clamp);
break;
case 1:
_PlayList->setWrapMode (i, UPlayList::Repeat);
break;
case 2:
_PlayList->setWrapMode (i, UPlayList::Disable);
break;
case 0:
_PlayList->setWrapMode (i, UPlayList::Clamp);
break;
case 1:
_PlayList->setWrapMode (i, UPlayList::Repeat);
break;
case 2:
_PlayList->setWrapMode (i, UPlayList::Disable);
break;
}
}
}

View file

@ -1,6 +1,6 @@
/*
Georges Editor Qt
Copyright (C) 2010 Adrian Jaekel <aj at elane2k dot com>
Object Viewer Qt
Copyright (C) 2010 Dzmitry Kamiahin <dnk-88@tut.by>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -14,21 +14,27 @@
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef ENTITY_H
#define ENTITY_H
#include <nel/misc/types_nl.h>
// STL includes
#include <map>
#include <string>
#include <vector>
// NeL includes
#include "nel/3d/animation_time.h"
#include <nel/misc/vector.h>
#include <nel/misc/vectord.h>
#include <nel/misc/quat.h>
#include <nel/3d/animation_time.h>
#include <nel/3d/u_instance.h>
#include <nel/3d/u_skeleton.h>
#include "nel/3d/channel_mixer.h"
#include <nel/3d/channel_mixer.h>
namespace NL3D {
class UPlayList;
@ -68,13 +74,15 @@ public:
/**
@class CEntity
Animated object. Allows you to upload animations for the shape.
@brief Class manage animated shape.
@details
Allows you to load animations for shape and skeleton weight.
Contains a built-in playlist. Has management and playback Playlists or Mixer.
*/
class CEntity
{
public:
struct Mode
struct Mode
{
enum List
{
@ -83,7 +91,7 @@ public:
};
};
// will need for a single or multiple reproduction
/// Will need for a single or multiple animation shape
struct SAnimationStatus
{
bool LoopAnim;
@ -100,9 +108,6 @@ public:
EndAnim(0), SpeedAnim(1), Mode(Mode::PlayList) {}
};
/// Constructor
CEntity(void);
/// Destructor
~CEntity(void);
@ -143,18 +148,38 @@ public:
void setSlotInfo(uint num, CSlotInfo& slotInfo) { _SlotInfo[num] = slotInfo; }
/// Set use mode playlist or mixer
void setMode(int mode) { _AnimationStatus.Mode = mode; }
void setMode(int mode) { _AnimationStatus.Mode = mode; }
/// Set in place mode animation
void setInPlace(bool enabled) { _inPlace = enabled; }
/// Get in place mode
bool getInPlace() { return _inPlace; }
/// Set inc position
void setIncPos(bool enabled) { _incPos = enabled; }
/// Get inc position
bool getIncPos() { return _incPos; }
/// Get information about the current status of playing a playlist
/// @return struct containing current information playback
SAnimationStatus& getStatus() { return _AnimationStatus; }
SAnimationStatus getStatus() { return _AnimationStatus; }
/// Get name entity
/// @return name entity
std::string &getName() { return _Name; }
std::string getName() { return _Name; }
/// Get file name shape
/// @return file name shape
std::string getFileNameShape() { return _FileNameShape; }
/// Get file name skeleton
/// @return file name skeleton
std::string getFileNameSkeleton() { return _FileNameSkeleton; }
/// Get slot information
CSlotInfo& getSlotInfo(uint num) { return _SlotInfo[num]; }
CSlotInfo getSlotInfo(uint num) { return _SlotInfo[num]; }
/// Get list loaded animations files
std::vector<std::string>& getAnimationList() { return _AnimationList; }
@ -165,7 +190,12 @@ public:
/// Get list loaded skeleton weight template files
std::vector<std::string>& getSWTList() { return _SWTList; }
/// Get game interface for manipulating Skeleton.
NL3D::USkeleton getSkeleton() const { return _Skeleton; }
private:
/// Constructor
CEntity(void);
/// Update the animate from the playlist or channel mixer
/// @param time - current time in second
@ -178,12 +208,24 @@ private:
/// Update the animate from the mixer
void animateChannelMixer();
void addTransformation (NLMISC::CMatrix &current, NL3D::UAnimation *anim,
float begin, float end,
NL3D::UTrack *posTrack, NL3D::UTrack *rotquatTrack,
NL3D::UTrack *nextPosTrack, NL3D::UTrack *nextRotquatTrack,
bool removeLast);
// The name of the entity
std::string _Name;
std::string _FileNameShape;
std::string _FileNameSkeleton;
SAnimationStatus _AnimationStatus;
bool _inPlace;
bool _incPos;
float _CharacterScalePos;
// The mesh instance associated to this entity
NL3D::UInstance _Instance;
@ -207,6 +249,7 @@ private:
CSlotInfo _SlotInfo[NL3D::CChannelMixer::NumAnimationSlot];
friend class CObjectViewer;
friend class CObjectViewerWidget;
}; /* class CEntity */
typedef std::map<std::string, CEntity> CEntities;

View file

@ -258,41 +258,35 @@ namespace NLQT
if(value.contains(".tga") || value.contains(".png"))
{
QString file = QFileDialog::getOpenFileName(
this,
"Select a new image",
path,
"Images (*.png *.tga)"
);
QFileInfo info = QFileInfo(file);
QString file = QFileDialog::getOpenFileName(
this,
"Select a new image",
path,
"Images (*.png *.tga)"
);
QFileInfo info = QFileInfo(file);
// TODO?
// right way would be another delegate but im too lazy :)
// so for now i just call it directly
m->setData(in2, info.fileName());
// TODO?
// right way would be another delegate but im too lazy :)
// so for now i just call it directly
m->setData(in2, info.fileName());
return;
}
else
{
if (path.contains(".shape"))
{
Modules::objView().resetScene();
//Modules::config().configRemapExtensions();
Modules::objView().loadMesh(path.toStdString(),"");
return;
}
}
return;
}
// col containing the display values
if (index.column() == 1)
{
//TODO rework this
CFormItem *item = m->getItem(in);
// open eg parent files
if (!path.isEmpty())
Q_EMIT changeFile(path);
QString value = item->data(1).toString();
QString path = CPath::lookup(value.toStdString(),false).c_str();
// open eg parent files
if (!path.isEmpty() && !path.contains(".shape"))
Q_EMIT changeFile(path);
if (path.contains(".shape"))
{
Modules::objView().resetScene();
//Modules::config().configRemapExtensions();
Modules::objView().loadMesh(path.toStdString(),"");
}
int i = 0;
}
}

View file

@ -45,7 +45,7 @@ namespace NLQT
QString comment, QStringList parents, QObject *parent) : QAbstractItemModel(parent)
{
QList<QVariant> rootData;
rootData << "Value" << "Data" << "Extra" << "Type";
rootData << "Value" << "Data" << "Extra";// << "Type";
_rootElm = rootElm;
_rootItem = new CFormItem(_rootElm, rootData);
_dependencies = deps;

View file

@ -20,6 +20,7 @@
NLQT::CConfiguration *Modules::_configuration = NULL;
NLQT::CObjectViewer *Modules::_objectViewer = NULL;
NLQT::CObjectViewerWidget *Modules::_objectViewerWidget = NULL;
NLQT::CGeorges *Modules::_georges = NULL;
NLQT::CMainWindow *Modules::_mainWindow = NULL;
@ -29,6 +30,7 @@ void Modules::init()
config().init();
if (_objectViewer == NULL) _objectViewer = new NLQT::CObjectViewer;
if (_objectViewerWidget == NULL) _objectViewerWidget = new NLQT::CObjectViewerWidget;
if (_georges == NULL) _georges = new NLQT::CGeorges;
if (_mainWindow == NULL) _mainWindow = new NLQT::CMainWindow;
}
@ -37,6 +39,7 @@ void Modules::release()
{
delete _mainWindow; _mainWindow = NULL;
delete _objectViewer; _objectViewer = NULL;
//delete _objectViewerWidget; _objectViewerWidget = NULL;
delete _georges; _georges = NULL;
config().release();

View file

@ -21,6 +21,7 @@
#include "configuration.h"
#include "object_viewer.h"
#include "object_viewer_widget.h"
#include "main_window.h"
#include "georges.h"
@ -32,11 +33,13 @@ public:
static NLQT::CConfiguration &config() { return *_configuration; }
static NLQT::CObjectViewer &objView() { return *_objectViewer; }
static NLQT::CObjectViewerWidget &objViewWid() { return *_objectViewerWidget; }
static NLQT::CGeorges &georges() { return *_georges;}
static NLQT::CMainWindow &mainWin() { return *_mainWindow; }
private:
static NLQT::CConfiguration *_configuration;
static NLQT::CObjectViewer *_objectViewer;
static NLQT::CObjectViewerWidget *_objectViewerWidget;
static NLQT::CMainWindow *_mainWindow;
static NLQT::CGeorges *_georges;
};

View file

@ -38,8 +38,9 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include <nel/3d/u_animation.h>
#include <nel/3d/u_play_list_manager.h>
#include <nel/3d/u_3d_mouse_listener.h>
#include <nel/3d/bloom_effect.h>
#include <nel/3d/event_mouse_listener.h>
//#include <nel/3d/event_mouse_listener.h>
// Project includes
#include "modules.h"
@ -53,9 +54,11 @@ namespace NLQT
{
CObjectViewer::CObjectViewer()
: _Driver(NULL),
_phi(0), _psi(0),_dist(20),
_CurrentInstance("")
: _Driver(NULL), _Light(0),
_phi(0), _psi(0),_dist(2),
_CameraFocal(75),
_CurrentInstance(""),
_BloomEffect(false), _Scene(0)
{
}
@ -71,20 +74,13 @@ namespace NLQT
//release();
//init(wnd, w, h);
_Driver->setDisplay(wnd, NL3D::UDriver::CMode(w, h, 32));
//_Driver->setDisplay(wnd, NL3D::UDriver::CMode(w, h, 32));
}
void CObjectViewer::init(nlWindow wnd, uint16 w, uint16 h)
{
//H_AUTO2
nldebug("CObjectViewer::init");
// load and set remap extensions from config
//Modules::config().configRemapExtensions();
// load and set search paths from config
//Modules::config().configSearchPaths();
// set background color from config
NLMISC::CConfigFile::CVar v = Modules::config().getConfigFile().getVar("BackgroundColor");
_BackgroundColor = CRGBA(v.asInt(0), v.asInt(1), v.asInt(2));
@ -101,36 +97,39 @@ namespace NLQT
else nlwarning("Invalid driver specified, defaulting to OpenGL");
#endif
//Modules::config().setAndCallback("CameraFocal",CConfigCallback(this,&CObjectViewer::cfcbCameraFocal));
//Modules::config().setAndCallback("BloomEffect",CConfigCallback(this,&CObjectViewer::cfcbBloomEffect));
// create the driver
nlassert(!_Driver);
_Driver = UDriver::createDriver(NULL, _Direct3D, NULL);
_Driver = UDriver::createDriver(0, _Direct3D, 0);
nlassert(_Driver);
// initialize the window with config file values
_Driver->setDisplay(wnd, NL3D::UDriver::CMode(w, h, 32));
_Light = ULight::createLight();
//_Light = ULight::createLight();
// set mode of the light
_Light->setMode(ULight::DirectionalLight);
//// set mode of the light
//_Light->setMode(ULight::DirectionalLight);
// set position of the light
_Light->setPosition(CVector(-20.f, 30.f, 10.f));
//// set position of the light
//_Light->setPosition(CVector(-20.f, 30.f, 10.f));
// white light
_Light->setAmbiant(CRGBA(255, 255, 255));
//// white light
//_Light->setAmbiant(CRGBA(255, 255, 255));
// set and enable the light
_Driver->setLight(0, *_Light);
_Driver->enableLight(0);
//// set and enable the light
//_Driver->setLight(0, *_Light);
//_Driver->enableLight(0);
// Create a scene
_Scene = _Driver->createScene(true);
_PlayListManager = _Scene->createPlayListManager();
_Scene->enableLightingSystem(true);
//_Scene->enableLightingSystem(true);
// create the camera
UCamera camera = _Scene->getCam();
@ -140,21 +139,27 @@ namespace NLQT
setSizeViewport(w, h);
// camera will look at entities
updateCamera(0,0,0);
camera.lookAt(NLMISC::CVector(_dist,0,1), NLMISC::CVector(0,0,0.5));
NLMISC::CVector hotSpot=NLMISC::CVector(0,0,0);
_MouseListener = _Driver->create3dMouseListener();
_MouseListener->setMatrix(Modules::objView().getScene()->getCam().getMatrix());
_MouseListener->setFrustrum(Modules::objView().getScene()->getCam().getFrustum());
_MouseListener->setMatrix(_Scene->getCam().getMatrix());
_MouseListener->setFrustrum(_Scene->getCam().getFrustum());
_MouseListener->setHotSpot(hotSpot);
_MouseListener->setMouseMode(U3dMouseListener::edit3d);
NL3D::CBloomEffect::instance().setDriver(_Driver);
NL3D::CBloomEffect::instance().setScene(_Scene);
NL3D::CBloomEffect::instance().init(!_Direct3D);
//NL3D::CBloomEffect::instance().setDensityBloom(Modules::config().getConfigFile().getVar("BloomDensity").asInt());
//NL3D::CBloomEffect::instance().setSquareBloom(Modules::config().getConfigFile().getVar("BloomSquare").asBool());
}
void CObjectViewer::release()
{
//H_AUTO2
nldebug("CObjectViewer::release");
nldebug("");
_Driver->delete3dMouseListener(_MouseListener);
@ -183,10 +188,17 @@ namespace NLQT
// New matrix from camera
_Scene->getCam().setTransformMode(NL3D::UTransformable::DirectMatrix);
_Scene->getCam().setMatrix (_MouseListener->getViewMatrix());
//nldebug("%s",_Scene->getCam().getMatrix().getPos().asString().c_str());
}
void CObjectViewer::renderDriver()
{
// Render the scene.
if((NL3D::CBloomEffect::instance().getDriver() != NULL) && (_BloomEffect))
{
NL3D::CBloomEffect::instance().initBloom();
}
_Driver->clearBuffers(_BackgroundColor);
}
@ -194,6 +206,12 @@ namespace NLQT
{
// render the scene
_Scene->render();
if((NL3D::CBloomEffect::instance().getDriver() != NULL) && (_BloomEffect))
{
NL3D::CBloomEffect::instance().endBloom();
NL3D::CBloomEffect::instance().endInterfacesDisplayBloom();
}
}
void CObjectViewer::renderDebug2D()
@ -238,22 +256,34 @@ namespace NLQT
bool CObjectViewer::loadMesh(const std::string &meshFileName, const std::string &skelFileName)
{
std::string fileName = CFile::getFilenameWithoutExtension(meshFileName);
if ( _Entities.count(fileName) != 0)
return false;
CPath::addSearchPath(CFile::getPath(meshFileName), false, false);
// create instance of the mesh character
UInstance Entity = _Scene->createInstance(meshFileName);
CAABBox bbox;
Entity.getShapeAABBox(bbox);
setCamera(bbox , Entity, true);
_MouseListener->setMatrix(_Scene->getCam().getMatrix());
USkeleton Skeleton = _Scene->createSkeleton(skelFileName);
// if we can't create entity, skip it
if (Entity.empty()) return false;
// create a new entity
EIT eit = (_Entities.insert (make_pair (CFile::getFilenameWithoutExtension(meshFileName), CEntity()))).first;
EIT eit = (_Entities.insert (make_pair (fileName, CEntity()))).first;
CEntity &entity = (*eit).second;
// set the entity up
entity._Name = CFile::getFilenameWithoutExtension(meshFileName);
entity._Name = fileName;
entity._FileNameShape = meshFileName;
entity._FileNameSkeleton = skelFileName;
entity._Instance = Entity;
if (!Skeleton.empty())
{
@ -285,27 +315,7 @@ namespace NLQT
void CObjectViewer::updateCamera(float deltaPsi, float deltaPhi, float deltaDist)
{
_phi += deltaPhi;
_psi += deltaPsi;
_dist += deltaDist;
if(_phi < -NLMISC::Pi/2) _phi -= deltaPhi;
if(_phi > NLMISC::Pi/2) _phi -= deltaPsi;
if (_dist < 1) _dist = 1;
NLMISC::CQuat q0,q1,q2;
NLMISC::CVector up(0,0,1);
NLMISC::CVector v(0,0,1);
q0.setAngleAxis(v,_psi);
v = NLMISC::CVector(0,1,0);
q1.setAngleAxis(v,_phi);
q2 = q0 * q1;
NLMISC::CMatrix m0;
m0.setRot(q2);
NLMISC::CVector camera = m0 * NLMISC::CVector(_dist,0,0);
_Scene->getCam().lookAt(camera, up);
}
void CObjectViewer::setBackgroundColor(NLMISC::CRGBA backgroundColor)
@ -328,13 +338,7 @@ namespace NLQT
void CObjectViewer::setSizeViewport(uint16 w, uint16 h)
{
_Scene->getCam().setPerspective((float)Pi/2.f, (float)w/h, 0.1f, 1000);
}
void CObjectViewer::getSizeViewport(float &left, float &right, float &bottom, float &top, float &znear, float &zfar)
{
//_Scene->getCam().setPerspective((float)Pi/2.f, (float)w/h, 0.1f, 1000);
_Scene->getCam().getFrustum(left, right, bottom, top, znear, zfar);
_Scene->getCam().setPerspective(_CameraFocal * (float)Pi/180.f, (float)w/h, 0.1f, 1000);
}
void CObjectViewer::setCurrentObject(const std::string &name)
@ -397,4 +401,141 @@ namespace NLQT
_Entities.clear();
}
void CObjectViewer::setCamera(CAABBox &bbox, UTransform &entity, bool high_z)
{
CVector pos(0.f, 0.f, 0.f);
CQuat quat(0.f, 0.f, 0.f, 0.f);
NL3D::UInstance inst;
inst.cast(entity);
if (!inst.empty())
{
inst.getDefaultPos(pos);
inst.getDefaultRotQuat(quat);
/*
if (quat.getAxis().isNull())
{
quat.set(0, 0, 0, 0);
inst.setRotQuat(quat);
}
*/
// quat.set(1.f, 1.f, 0.f, 0.f);
// inst.setRotQuat(quat);
// inst.getRotQuat(quat);
// check for presence of all textures from each sets
//bool allGood = true;
//for(uint s = 0; s < 5; ++s)
//{
// inst.selectTextureSet(s);
// uint numMat = inst.getNumMaterials();
// // by default, all textures are present
// allGood = true;
// for(uint i = 0; i < numMat; ++i)
// {
// UInstanceMaterial mat = inst.getMaterial(i);
// for(sint j = 0; j <= mat.getLastTextureStage(); ++j)
// {
// // if a texture is missing
// if (mat.isTextureFile(j) && mat.getTextureFileName(j) == "CTextureMultiFile:Dummy")
// allGood = false;
// }
// }
// // if all textures have been found for this set, skip other sets
// if (allGood)
// break;
//}
}
// fix scale (some shapes have a different value)
entity.setScale(1.f, 1.f, 1.f);
UCamera Camera = _Scene->getCam();
CVector max_radius = bbox.getHalfSize();
CVector center = bbox.getCenter();
entity.setPivot(center);
center += pos;
//_Scene->getCam().setPerspective(_CameraFocal * (float)Pi/180.f, (float)w/h, 0.1f, 1000);
float fov = float(_CameraFocal * (float)Pi/180.0);
//Camera.setPerspective (fov, 1.0f, 0.1f, 1000.0f);
float radius = max(max(max_radius.x, max_radius.y), max_radius.z);
if (radius == 0.f) radius = 1.f;
float left, right, bottom, top, znear, zfar;
Camera.getFrustum(left, right, bottom, top, znear, zfar);
float dist = radius / (tan(fov/2));
CVector eye(center);
/* if (axis == CVector::I)
eye.y -= dist+radius;
else if (axis == CVector::J)
eye.x += dist+radius;
*/
// quat.normalize();
CVector ax(quat.getAxis());
// float angle = quat.getAngle();
/*
if (ax.isNull())
{
if (int(angle*100.f) == int(NLMISC::Pi * 200.f))
{
ax = CVector::J;
}
}
else
*/
if (ax.isNull() || ax == CVector::I)
{
ax = CVector::J;
}
else if (ax == -CVector::K)
{
ax = -CVector::J;
}
/* else if (ax.x < -0.9f && ax.y == 0.f && ax.z == 0.f)
{
ax = -CVector::J ;
}
*/
// ax.normalize();
eye -= ax * (dist+radius);
if (high_z)
eye.z += max_radius.z/1.0f;
Camera.lookAt(eye, center);
setupLight(eye, center - eye);
}
bool CObjectViewer::setupLight(const CVector &position, const CVector &direction)
{
if (!_Light)
_Light = ULight::createLight();
if (!_Light) return false;
// set mode of the light
_Light->setMode(ULight::DirectionalLight);
// set position of the light
// Light->setupDirectional(settings.light_ambiant, settings.light_diffuse, settings.light_specular, settings.light_direction);
NLMISC::CRGBA light_ambiant = CRGBA(0,0,0);
NLMISC::CRGBA light_diffuse = CRGBA(255,255,255);
NLMISC::CRGBA light_specular = CRGBA(255,255,255);
NLMISC::CVector light_direction = CVector(0.25, 0.25, 0.25);
_Light->setupPointLight(light_ambiant, light_diffuse, light_specular, position, direction + light_direction);
// set and enable the light
_Driver->setLight(0, *_Light);
_Driver->enableLight(0);
return true;
}
} /* namespace NLQT */

View file

@ -29,6 +29,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include <nel/misc/config_file.h>
#include <nel/misc/rgba.h>
#include <nel/3d/event_mouse_listener.h>
#include <nel/misc/aabbox.h>
// Project includes
#include "entity.h"
@ -117,7 +118,8 @@ namespace NLQT
/// @param w - width window.
/// @param h - height window.
void setSizeViewport(uint16 w, uint16 h);
void getSizeViewport(float &left, float &right, float &bottom, float &top, float &znear, float &zfar);
void setBloomEffect(bool enabled) { _BloomEffect = enabled; }
/// Select instance from the scene
/// @param name - name instance, "" if no instance edited
@ -143,6 +145,8 @@ namespace NLQT
/// @return true if have used Direct3D driver, false OpenGL driver.
inline bool getDirect3D() { return _Direct3D; }
inline bool getBloomEffect() const { return _BloomEffect; }
/// Get a pointer to the driver.
/// @return pointer to the driver.
inline NL3D::UDriver *getDriver() { return _Driver; }
@ -155,6 +159,9 @@ namespace NLQT
/// @return pointer to the UPlayListManager
inline NL3D::UPlayListManager *getPlayListManager() { return _PlayListManager; }
void setCamera(NLMISC::CAABBox &bbox, NL3D::UTransform &entity, bool high_z);
bool setupLight(const NLMISC::CVector &position, const NLMISC::CVector &direction);
private:
void deleteEntity (CEntity &entity);
@ -165,18 +172,20 @@ namespace NLQT
NL3D::UDriver *_Driver;
NL3D::UScene *_Scene;
NL3D::UPlayListManager *_PlayListManager;
NL3D::UPlayListManager *_PlayListManager;
NL3D::ULight *_Light;
NL3D::UCamera *_Camera;
NL3D::U3dMouseListener *_MouseListener;
NL3D::U3dMouseListener *_MouseListener;
// The entities storage
CEntities _Entities;
/// Camera parameters.
float _phi, _psi, _dist;
float _CameraFocal;
bool _Direct3D;
bool _BloomEffect;
std::string _CurrentInstance;

View file

@ -0,0 +1,119 @@
/*
Georges Editor Qt
Copyright (C) 2010 Adrian Jaekel <aj at elane2k dot com>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "object_viewer_widget.h"
// STL includes
// NeL includes
#include <nel/3d/driver_user.h>
// Project includes
#include "modules.h"
namespace NLQT
{
CObjectViewerWidget::CObjectViewerWidget()
{
}
CObjectViewerWidget::~CObjectViewerWidget()
{
}
void CObjectViewerWidget::setVisible(bool visible)
{
// called by show()
// code assuming visible window needed to init the 3d driver
nldebug("%d", visible);
if (visible)
{
QWidget::setVisible(true);
}
else
{
QWidget::setVisible(false);
}
}
#if defined(NL_OS_WINDOWS)
typedef bool (*winProc)(NL3D::IDriver *driver, HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
bool CObjectViewerWidget::winEvent(MSG * message, long * result)
{
if (Modules::objView().getDriver() &&
Modules::objView().getDriver()->isActive())
{
NL3D::IDriver *driver = dynamic_cast<NL3D::CDriverUser*>(Modules::objView().getDriver())->getDriver();
if (driver)
{
winProc proc = (winProc)driver->getWindowProc();
return proc(driver, message->hwnd, message->message, message->wParam, message->lParam);
}
}
return false;
}
#elif defined(NL_OS_MAC)
typedef bool (*cocoaProc)(NL3D::IDriver*, const void* e);
bool CObjectViewerWidget::macEvent(EventHandlerCallRef caller, EventRef event)
{
if(caller)
nlerror("You are using QtCarbon! Only QtCocoa supported, please upgrade Qt");
if (Modules::objView().getDriver() && Modules::objView().getDriver()->isActive())
{
NL3D::IDriver *driver = dynamic_cast<NL3D::CDriverUser*>(Modules::objView().getDriver())->getDriver();
if (driver)
{
cocoaProc proc = (cocoaProc)driver->getWindowProc();
return proc(driver, event);
}
}
return false;
}
#elif defined(NL_OS_UNIX)
typedef bool (*x11Proc)(NL3D::IDriver *drv, XEvent *e);
bool CObjectViewerWidget::x11Event(XEvent *event)
{
if (Modules::objView().getDriver() && Modules::objView().getDriver()->isActive())
{
NL3D::IDriver *driver = dynamic_cast<NL3D::CDriverUser*>(Modules::objView().getDriver())->getDriver();
if (driver)
{
x11Proc proc = (x11Proc)driver->getWindowProc();
return proc(driver, event);
}
}
return false;
}
#endif
} /* namespace NLQT */

View file

@ -0,0 +1,61 @@
/*
Georges Editor Qt
Copyright (C) 2010 Adrian Jaekel <aj at elane2k dot com>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef OBJECT_VIEWER_WIDGET_H
#define OBJECT_VIEWER_WIDGET_H
// STL includes
// NeL includes
// Qt includes
#include <QtOpenGL/QGLWidget>
// Project includes
/**
namespace NLQT
@brief namespace NLQT
*/
namespace NLQT
{
class CObjectViewerWidget: public QWidget
{
Q_OBJECT
public:
/// Default constructor.
CObjectViewerWidget();
virtual ~CObjectViewerWidget();
virtual void setVisible(bool visible);
protected:
#if defined(NL_OS_WINDOWS)
virtual bool winEvent(MSG * message, long * result);
#elif defined(NL_OS_MAC)
virtual bool macEvent(EventHandlerCallRef caller, EventRef event);
#elif defined(NL_OS_UNIX)
virtual bool x11Event(XEvent *event);
#endif
};/* class CObjectViewerWidget */
} /* namespace NLQT */
#endif // OBJECT_VIEWER_WIDGET_H

View file

@ -30,8 +30,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include <nel/misc/events.h>
#include <nel/3d/u_driver.h>
#include <nel/3d/u_camera.h>
#include <nel/3d/u_scene.h>
#include <nel/3d/driver_user.h>
// Project includes
#include "modules.h"
@ -47,9 +46,11 @@ namespace NLQT
{
_ui.setupUi(this);
_nlw = new QNLWidget(_ui.dockWidgetContents);
_nlw->setObjectName(QString::fromUtf8("nlwidget"));
_ui.gridLayout->addWidget(_nlw, 0, 0, 1, 1);
// _nlw = new QNLWidget(_ui.dockWidgetContents);
_nlw = &Modules::objViewWid();
//_nlw->setObjectName(QString::fromUtf8("nlwidget"));
_ui.gridLayout->addWidget(_nlw, 0, 0);
//nlw->setLayout(new QGridLayout(nlw));
//_ui.widget = nlw;
//QWidget * w = widget();
@ -62,7 +63,7 @@ namespace NLQT
connect(_mainTimer, SIGNAL(timeout()), this, SLOT(updateRender()));
// timer->start(); // <- timeout 0
// it's heavy on cpu, though, when no 3d driver initialized :)
_mainTimer->start(5); // 25fps
_mainTimer->start(25); // 25fps
}
CObjectViewerDialog::~CObjectViewerDialog()
@ -75,28 +76,38 @@ namespace NLQT
connect(this, SIGNAL(topLevelChanged(bool)),
this, SLOT(topLevelChanged(bool)));
//H_AUTO2
nldebug("CObjectViewerDialog::init %d",_nlw->winId());
//nldebug("%d %d %d",_nlw->winId(), width(), height());
#if defined(NL_OS_UNIX) && !defined(NL_OS_MAC)
dynamic_cast<QNLWidget*>(widget())->makeCurrent();
#endif // defined(NL_OS_UNIX) && !defined(NL_OS_MAC)
Modules::objView().init((nlWindow)_nlw->winId(), 20, 20);
Modules::objView().init((nlWindow)_nlw->winId(), width(), height());
setMouseTracking(true);
}
void CObjectViewerDialog::release()
{
nldebug("");
Modules::objView().release();
}
void CObjectViewerDialog::setVisible(bool visible)
{
// called by show()
// code assuming visible window needed to init the 3d driver
nldebug("%d", visible);
if (visible)
{
QDockWidget::setVisible(true);
updateInitialization(true);
_mainTimer->start(25);
//updateInitialization(true);
//_nlw->show();
}
else
{
updateInitialization(false);
//updateInitialization(false);
QDockWidget::setVisible(false);
}
}
@ -121,12 +132,11 @@ namespace NLQT
{
if (!wantGraphics)
{
_isGraphicsInitialized = false;
release();
//_isGraphicsInitialized = false;
//release();
_mainTimer->stop();
done = false;
//done = false;
}
}
else
{
@ -134,8 +144,8 @@ namespace NLQT
{
init();
_isGraphicsInitialized = true;
_mainTimer->start(5);
done = false;
_mainTimer->start(25);
//done = false;
}
}
}
@ -237,23 +247,6 @@ namespace NLQT
}
}
void CObjectViewerDialog::release()
{
//H_AUTO2
nldebug("CObjectViewerDialog::release");
Modules::objView().release();
}
void CObjectViewerDialog::reinit()
{
//H_AUTO2
nldebug("CObjectViewerDialog::reinit");
Modules::objView().release();
//Modules::objView().reinit(_ui.frame->winId(), width(), height());
}
QAction *CObjectViewerDialog::createSaveScreenshotAction(QObject *parent)
{
QAction *action = new QAction(parent);
@ -283,18 +276,18 @@ namespace NLQT
void CObjectViewerDialog::topLevelChanged ( bool topLevel ) {
//nldebug("CObjectViewerDialog::topLevelChanged topLevel:%d",topLevel);
nldebug("CObjectViewerDialog::topLevelChanged winId:%d",winId());
//nldebug("%d %d",winId(), _nlw->winId());
// winId changing when re/docking
//Modules::georges().init();
Modules::objView().reinit((nlWindow)_nlw->winId(), _nlw->width(), _nlw->height());
//Modules::objView().reinit((nlWindow)_nlw->winId(), _nlw->width(), _nlw->height());
}
void CObjectViewerDialog::resizeEvent(QResizeEvent *resizeEvent)
{
//nldebug("%d %d",_nlw->width(), _nlw->height());
QDockWidget::resizeEvent(resizeEvent);
if (Modules::objView().getDriver())
Modules::objView().setSizeViewport(resizeEvent->size().width(), resizeEvent->size().height());
// The OpenGL driver does not resize automatically.
// The Direct3D driver breaks the window mode to include window borders when calling setMode windowed.
@ -302,105 +295,4 @@ namespace NLQT
// There is probably something inside the drivers not being released properly.
}
void CObjectViewerDialog::wheelEvent(QWheelEvent *event)
{
//nldebug("CObjectViewerDialog::wheelEvent");
// Get relative positions.
float fX = 1.0f - (float)event->pos().x() / this->width();
float fY = 1.0f - (float)event->pos().y() / this->height();
// Set the buttons currently pressed.
NLMISC::TMouseButton buttons = (NLMISC::TMouseButton)getNelButtons(event);
if(event->delta() > 0)
Modules::objView().getDriver()->EventServer.postEvent(new NLMISC::CEventMouseWheel(-fX, fY, buttons, true, this));
else
Modules::objView().getDriver()->EventServer.postEvent(new NLMISC::CEventMouseWheel(-fX, fY, buttons, false, this));
}
uint32 CObjectViewerDialog::getNelButtons(QMouseEvent *event)
{
//nldebug("CObjectViewerDialog::getNelButtons");
uint32 buttons = NLMISC::noButton;
if(event->buttons() & Qt::LeftButton) buttons |= NLMISC::leftButton;
if(event->buttons() & Qt::RightButton) buttons |= NLMISC::rightButton;
if(event->buttons() & Qt::MidButton) buttons |= NLMISC::middleButton;
if(event->modifiers() & Qt::ControlModifier) buttons |= NLMISC::ctrlButton;
if(event->modifiers() & Qt::ShiftModifier) buttons |= NLMISC::shiftButton;
if(event->modifiers() & Qt::AltModifier) buttons |= NLMISC::altButton;
return buttons;
}
uint32 CObjectViewerDialog::getNelButtons(QWheelEvent *event)
{
//nldebug("CObjectViewerDialog::getNelButtons");
uint32 buttons = NLMISC::noButton;
if(event->buttons() & Qt::LeftButton) buttons |= NLMISC::leftButton;
if(event->buttons() & Qt::RightButton) buttons |= NLMISC::rightButton;
if(event->buttons() & Qt::MidButton) buttons |= NLMISC::middleButton;
if(event->modifiers() & Qt::ControlModifier) buttons |= NLMISC::ctrlButton;
if(event->modifiers() & Qt::ShiftModifier) buttons |= NLMISC::shiftButton;
if(event->modifiers() & Qt::AltModifier) buttons |= NLMISC::altButton;
return buttons;
}
void CObjectViewerDialog::mousePressEvent(QMouseEvent *event)
{
//nldebug("CObjectViewerDialog::mousePressEvent");
// Get relative positions.
float fX = 1.0f - (float)event->pos().x() / this->width();
float fY = 1.0f - (float)event->pos().y() / this->height();
// Set the buttons currently pressed.
NLMISC::TMouseButton buttons = (NLMISC::TMouseButton)getNelButtons(event);
if(event->button() == Qt::LeftButton)
Modules::objView().getDriver()->EventServer.postEvent(
new NLMISC::CEventMouseDown( -fX, fY,
(NLMISC::TMouseButton)(NLMISC::leftButton|(buttons&~(NLMISC::leftButton|NLMISC::middleButton|NLMISC::rightButton))), this));
if(event->button() == Qt::MidButton)
Modules::objView().getDriver()->EventServer.postEvent(
new NLMISC::CEventMouseDown( -fX, fY,
(NLMISC::TMouseButton)(NLMISC::middleButton|(buttons&~(NLMISC::middleButton|NLMISC::leftButton|NLMISC::rightButton))), this));
if(event->button() == Qt::RightButton)
Modules::objView().getDriver()->EventServer.postEvent(
new NLMISC::CEventMouseDown( -fX, fY,
(NLMISC::TMouseButton)(NLMISC::rightButton|(buttons&~(NLMISC::rightButton|NLMISC::leftButton|NLMISC::middleButton))), this));
}
void CObjectViewerDialog::mouseReleaseEvent(QMouseEvent *event)
{
//nldebug("CObjectViewerDialog::mouseReleaseEvent");
// Get relative positions.
float fX = 1.0f - (float)event->pos().x() / this->width();
float fY = 1.0f - (float)event->pos().y() / this->height();
// Set the buttons currently pressed.
NLMISC::TMouseButton buttons = (NLMISC::TMouseButton)getNelButtons(event);
if(event->button() == Qt::LeftButton)
Modules::objView().getDriver()->EventServer.postEvent(
new NLMISC::CEventMouseUp( -fX, fY, NLMISC::leftButton, this));
if(event->button() == Qt::MidButton)
Modules::objView().getDriver()->EventServer.postEvent(
new NLMISC::CEventMouseUp( -fX, fY, NLMISC::middleButton, this));
if(event->button() == Qt::RightButton)
Modules::objView().getDriver()->EventServer.postEvent(
new NLMISC::CEventMouseUp( -fX, fY, NLMISC::rightButton, this));
}
void CObjectViewerDialog::mouseMoveEvent(QMouseEvent *event)
{
//nldebug("CObjectViewerDialog::mouseMoveEvent");
// Get relative positions.
float fX = 1.0f - (float)event->pos().x() / this->width();
float fY = 1.0f - (float)event->pos().y() / this->height();
if ((fX == 0.5f) && (fY == 0.5f)) return;
NLMISC::TMouseButton buttons = (NLMISC::TMouseButton)getNelButtons(event);
Modules::objView().getDriver()->EventServer.postEvent(new NLMISC::CEventMouseMove(-fX, fY, buttons, this));
}
} /* namespace NLQT */

View file

@ -50,7 +50,7 @@ class QAction;
namespace NLQT
{
class CObjectViewerDialog: public QDockWidget, public NLMISC::IEventEmitter
class CObjectViewerDialog: public QDockWidget
{
Q_OBJECT
@ -59,7 +59,7 @@ namespace NLQT
~CObjectViewerDialog();
virtual void setVisible(bool visible);
// virtual QPaintEngine* paintEngine() const { return NULL; }
virtual QPaintEngine* paintEngine() const { return NULL; }
void init();
void release();
@ -74,20 +74,13 @@ namespace NLQT
void saveScreenshot();
void setBackgroundColor();
void submitEvents(NLMISC::CEventServer &server, bool allWindows) { };
void emulateMouseRawMode(bool) { };
void submitEvents(NLMISC::CEventServer &server, bool allWindows) { }
void emulateMouseRawMode(bool) { }
void topLevelChanged(bool topLevel);
protected:
virtual void resizeEvent(QResizeEvent *resizeEvent);
virtual void mousePressEvent(QMouseEvent *event);
virtual void mouseReleaseEvent(QMouseEvent *event);
virtual void wheelEvent(QWheelEvent *event);
virtual void mouseMoveEvent(QMouseEvent *event);
uint32 getNelButtons(QMouseEvent *event);
uint32 getNelButtons(QWheelEvent *event);
private:
CObjectViewerDialog(const CObjectViewerDialog &);