mirror of https://github.com/Poikilos/b3view
improve ui, target, improve pan
parent
fe7e4c6a5c
commit
036c0feb01
23
CHANGELOG.md
23
CHANGELOG.md
|
@ -1,5 +1,28 @@
|
|||
# Changelog
|
||||
|
||||
## [git] - 2019-04-18
|
||||
(poikilos)
|
||||
### Added
|
||||
* box for axis length (size of the axis widget)
|
||||
* box for frame rate
|
||||
|
||||
### Changed
|
||||
* Reorder boxes.
|
||||
* Changed hotkeys so they aren't triggered when typing in the panel.
|
||||
|
||||
## [git] - 2019-04-08
|
||||
(poikilos)
|
||||
### Added
|
||||
* snapWidgets (move playbackWindow on resize, not leave past edge)
|
||||
|
||||
### Changed
|
||||
* changed enum values to leave room in between, comment unused
|
||||
* fixed issue in Utility not detecting backslashes correctly
|
||||
* renamed Utils.* to Utility.* to match class name
|
||||
* coding style to WebKit (run ./etc/quality.sh to check)
|
||||
* improve pan - don't reset view
|
||||
* improve initial camera settings: angle calculation
|
||||
|
||||
## [git] - 2019-04-08
|
||||
(poikilos)
|
||||
### Added
|
||||
|
|
151
Engine.cpp
151
Engine.cpp
|
@ -34,7 +34,7 @@ void Engine::setupScene()
|
|||
|
||||
// Setup Camera
|
||||
// (so z-forward characters face camera partially (formerly vector3df(0, 0, -10), vector3df())
|
||||
m_CamPos = vector3df(4.5, 3, 9);
|
||||
m_CamPos = vector3df(4.5, 3.5, 9);
|
||||
m_CamTarget = vector3df(0, 3, 0);
|
||||
ICameraSceneNode* camera = m_Scene->addCameraSceneNode(nullptr, m_CamPos, m_CamTarget); // this will be overridden by View m_Yaw and m_Pitch--see "calculate m_Yaw" further down
|
||||
camera->setAspectRatio(static_cast<f32>(m_Driver->getScreenSize().Width) / static_cast<f32>(m_Driver->getScreenSize().Height));
|
||||
|
@ -47,44 +47,109 @@ IGUIEnvironment* Engine::getGUIEnvironment() const
|
|||
|
||||
void Engine::drawAxisLines()
|
||||
{
|
||||
SMaterial* lineX = new SMaterial();
|
||||
lineX->Lighting = false;
|
||||
lineX->EmissiveColor = SColor(255, 255, 0, 0);
|
||||
lineX->Thickness = 1.0f;
|
||||
SMaterial xMaterial;
|
||||
xMaterial.Lighting = false;
|
||||
xMaterial.EmissiveColor = SColor(255, 255, 0, 0);
|
||||
xMaterial.Thickness = 1.0f;
|
||||
|
||||
SMaterial* lineY = new SMaterial(*lineX);
|
||||
lineY->EmissiveColor = SColor(255, 0, 255, 0);
|
||||
SMaterial yMaterial(xMaterial);
|
||||
yMaterial.EmissiveColor = SColor(255, 0, 255, 0);
|
||||
|
||||
SMaterial* lineZ = new SMaterial(*lineX);
|
||||
lineZ->EmissiveColor = SColor(255, 0, 0, 255);
|
||||
SMaterial zMaterial(xMaterial);
|
||||
zMaterial.EmissiveColor = SColor(255, 0, 0, 255);
|
||||
|
||||
SMaterial descenderMaterialVert(xMaterial);
|
||||
descenderMaterialVert.EmissiveColor = SColor(128, 128, 128, 128); // ARGB
|
||||
SMaterial descenderMaterialHorz(xMaterial);
|
||||
descenderMaterialHorz.EmissiveColor = SColor(255, 255, 255, 255);
|
||||
|
||||
vector3df descend3df(0, 0, 0);
|
||||
// vector3df target = m_View->c
|
||||
|
||||
m_Driver->setTransform(ETS_WORLD, matrix4());
|
||||
|
||||
m_Driver->setMaterial(*lineX);
|
||||
m_Driver->draw3DLine(vector3df(), vector3df(5, 0, 0), SColor(255, 255, 0, 0));
|
||||
position2d<s32> textPos = m_Scene->getSceneCollisionManager()->getScreenCoordinatesFrom3DPosition(vector3df(5.2f, 0, 0));
|
||||
if (m_View != nullptr) {
|
||||
if (this->m_UserInterface->viewMenu->isItemChecked(this->m_UserInterface->viewTargetIdx)) {
|
||||
if (m_View->zUp()) {
|
||||
descend3df.Z = this->m_CamTarget.Z;
|
||||
}
|
||||
else {
|
||||
descend3df.Y = this->m_CamTarget.Y;
|
||||
}
|
||||
vector3df descendSideways3df(descend3df);
|
||||
descendSideways3df.X = this->m_CamTarget.X;
|
||||
vector3df descendSidewaysForward3df(descendSideways3df);
|
||||
if (m_View->zUp()) {
|
||||
descendSidewaysForward3df.Y = this->m_CamTarget.Y;
|
||||
}
|
||||
else {
|
||||
descendSidewaysForward3df.Z = this->m_CamTarget.Z;
|
||||
}
|
||||
m_Driver->setMaterial(descenderMaterialVert);
|
||||
m_Driver->draw3DLine(vector3df(), descend3df, descenderMaterialVert.EmissiveColor);
|
||||
m_Driver->setMaterial(descenderMaterialHorz);
|
||||
m_Driver->draw3DLine(descend3df, descendSideways3df, descenderMaterialHorz.EmissiveColor);
|
||||
m_Driver->draw3DLine(descendSideways3df, descendSidewaysForward3df, descenderMaterialHorz.EmissiveColor);
|
||||
f32 arrowDirection = 1.0f;
|
||||
vector3df arrowLeft3df(descendSidewaysForward3df);
|
||||
vector3df arrowRight3df(descendSidewaysForward3df);
|
||||
f32 arrowSize = this->m_View->cameraDistance() / 30;
|
||||
if (m_View->zUp()) {
|
||||
if (descendSidewaysForward3df.Y > descendSideways3df.Y)
|
||||
arrowDirection = -1.0f;
|
||||
arrowLeft3df.X += arrowSize;
|
||||
arrowLeft3df.Y += arrowSize * arrowDirection;
|
||||
arrowRight3df.X -= arrowSize;
|
||||
arrowRight3df.Y += arrowSize * arrowDirection;
|
||||
}
|
||||
else {
|
||||
if (descendSidewaysForward3df.Z > descendSideways3df.Z)
|
||||
arrowDirection = -1.0f;
|
||||
arrowLeft3df.X += arrowSize;
|
||||
arrowLeft3df.Z += arrowSize * arrowDirection;
|
||||
arrowRight3df.X -= arrowSize;
|
||||
arrowRight3df.Z += arrowSize * arrowDirection;
|
||||
}
|
||||
m_Driver->draw3DLine(descendSidewaysForward3df, arrowLeft3df, descenderMaterialHorz.EmissiveColor);
|
||||
m_Driver->draw3DLine(descendSidewaysForward3df, arrowRight3df, descenderMaterialHorz.EmissiveColor);
|
||||
// position2d<s32> targetPos2d = m_Scene->getSceneCollisionManager()->getScreenCoordinatesFrom3DPosition(this->m_CamTarget);
|
||||
// dimension2d<u32> textSize;
|
||||
// if (m_AxisFont != nullptr) {
|
||||
// textSize = m_AxisFont->getDimension(L"target");
|
||||
// m_AxisFont->draw(L"target", rect<s32>(targetPos2d, textSize), descenderMaterial.EmissiveColor, true, true);
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
m_Driver->setMaterial(xMaterial);
|
||||
m_Driver->draw3DLine(vector3df(), vector3df(axisLength, 0, 0), SColor(255, 255, 0, 0));
|
||||
position2d<s32> textPos = m_Scene->getSceneCollisionManager()->getScreenCoordinatesFrom3DPosition(vector3df(axisLength + axisLength*.1f, 0, 0));
|
||||
dimension2d<u32> textSize;
|
||||
if (m_AxisFont != nullptr) {
|
||||
textSize = m_AxisFont->getDimension(L"X+");
|
||||
m_AxisFont->draw(L"X+", rect<s32>(textPos, textSize), SColor(255, 255, 0, 0), true, true);
|
||||
}
|
||||
m_Driver->setMaterial(*lineY);
|
||||
m_Driver->draw3DLine(vector3df(), vector3df(0, 5, 0), SColor(255, 0, 255, 0));
|
||||
textPos = m_Scene->getSceneCollisionManager()->getScreenCoordinatesFrom3DPosition(vector3df(0, 5.2f, 0));
|
||||
|
||||
m_Driver->setMaterial(yMaterial);
|
||||
m_Driver->draw3DLine(vector3df(), vector3df(0, axisLength, 0), SColor(255, 0, 255, 0));
|
||||
textPos = m_Scene->getSceneCollisionManager()->getScreenCoordinatesFrom3DPosition(vector3df(0, axisLength + axisLength*.1f, 0));
|
||||
if (m_AxisFont != nullptr) {
|
||||
textSize = m_AxisFont->getDimension(L"Y+");
|
||||
m_AxisFont->draw(L"Y+", rect<s32>(textPos, textSize), SColor(255, 0, 255, 0), true, true);
|
||||
}
|
||||
m_Driver->setMaterial(*lineZ);
|
||||
m_Driver->draw3DLine(vector3df(), vector3df(0, 0, 5), SColor(255, 0, 0, 255));
|
||||
textPos = m_Scene->getSceneCollisionManager()->getScreenCoordinatesFrom3DPosition(vector3df(0, 0, 5.2f));
|
||||
|
||||
m_Driver->setMaterial(zMaterial);
|
||||
m_Driver->draw3DLine(vector3df(), vector3df(0, 0, axisLength), SColor(255, 0, 0, 255));
|
||||
textPos = m_Scene->getSceneCollisionManager()->getScreenCoordinatesFrom3DPosition(vector3df(0, 0, axisLength + axisLength*.1f));
|
||||
if (m_AxisFont != nullptr) {
|
||||
textSize = m_AxisFont->getDimension(L"Z+");
|
||||
m_AxisFont->draw(L"Z+", rect<s32>(textPos, textSize), SColor(255, 0, 0, 255), true, true);
|
||||
}
|
||||
delete lineX;
|
||||
delete lineY;
|
||||
delete lineZ;
|
||||
//delete xMaterial;
|
||||
//delete yMaterial;
|
||||
//delete zMaterial;
|
||||
}
|
||||
|
||||
void Engine::drawBackground()
|
||||
|
@ -141,7 +206,7 @@ Engine::Engine()
|
|||
keyState[i] = 0;
|
||||
LMouseState = 0;
|
||||
RMouseState = 0;
|
||||
|
||||
this->axisLength = 10;
|
||||
this->worldFPS = 60;
|
||||
this->prevFPS = 30;
|
||||
this->textureExtensions.push_back(L"png");
|
||||
|
@ -205,6 +270,11 @@ Engine::~Engine()
|
|||
delete m_AxisFontFace;
|
||||
}
|
||||
|
||||
vector3df Engine::camTarget()
|
||||
{
|
||||
return m_CamTarget;
|
||||
}
|
||||
|
||||
void Engine::loadMesh(const wstring& fileName)
|
||||
{
|
||||
this->m_PreviousPath = fileName; // even if bad, set this
|
||||
|
@ -223,6 +293,7 @@ void Engine::loadMesh(const wstring& fileName)
|
|||
m_View->setZUp(false);
|
||||
}
|
||||
if (m_LoadedMesh != nullptr) {
|
||||
this->m_UserInterface->playbackFPSEditBox->setText(Utility::toWstring(m_LoadedMesh->getAnimationSpeed()).c_str());
|
||||
ICameraSceneNode* camera = this->m_Scene->getActiveCamera();
|
||||
aabbox3d<f32> box = m_LoadedMesh->getTransformedBoundingBox();
|
||||
//vector3d<float> extents = box.getExtent();
|
||||
|
@ -288,14 +359,16 @@ void Engine::reloadTexture()
|
|||
|
||||
bool Engine::loadTexture(const wstring& fileName)
|
||||
{
|
||||
ITexture* texture = this->m_Driver->getTexture(fileName.c_str());
|
||||
bool ret = false;
|
||||
if (texture != nullptr) {
|
||||
m_LoadedMesh->setMaterialTexture(0, texture);
|
||||
ret = true;
|
||||
if (m_LoadedMesh != nullptr) {
|
||||
ITexture* texture = this->m_Driver->getTexture(fileName.c_str());
|
||||
if (texture != nullptr) {
|
||||
m_LoadedMesh->setMaterialTexture(0, texture);
|
||||
ret = true;
|
||||
}
|
||||
this->m_PrevTexturePath = fileName;
|
||||
this->m_UserInterface->texturePathEditBox->setText(this->m_PrevTexturePath.c_str());
|
||||
}
|
||||
this->m_PrevTexturePath = fileName;
|
||||
this->m_UserInterface->texturePathEditBox->setText(this->m_PrevTexturePath.c_str());
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -385,7 +458,25 @@ void Engine::toggleAnimation()
|
|||
void Engine::setAnimationFPS(u32 animationFPS)
|
||||
{
|
||||
if (this->m_LoadedMesh != nullptr) {
|
||||
if (animationFPS > 0) this->isPlaying = true;
|
||||
// Do NOT call playAnimation, otherwise infinite recursion occurs (it calls setAnimationFPS).
|
||||
this->m_LoadedMesh->setAnimationSpeed(animationFPS);
|
||||
this->m_UserInterface->playbackFPSEditBox->setText(Utility::toWstring(this->m_LoadedMesh->getAnimationSpeed()).c_str());
|
||||
}
|
||||
}
|
||||
|
||||
void Engine::incrementAnimationFPS(irr::f32 by)
|
||||
{
|
||||
if (this->m_LoadedMesh != nullptr) {
|
||||
if (by < 0) {
|
||||
if (this->m_LoadedMesh->getAnimationSpeed() + by >= 0.999999f) // don't use this->animationFPS(), because its unsigned!
|
||||
this->setAnimationFPS(this->m_LoadedMesh->getAnimationSpeed() + by);
|
||||
else
|
||||
this->setAnimationFPS(1);
|
||||
}
|
||||
else {
|
||||
this->setAnimationFPS(this->animationFPS() + by);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -398,11 +489,11 @@ void Engine::setZUp(bool zUp)
|
|||
|
||||
u32 Engine::animationFPS()
|
||||
{
|
||||
u32 ret = 0;
|
||||
f32 ret = 0;
|
||||
if (this->m_LoadedMesh != nullptr) {
|
||||
ret = this->m_LoadedMesh->getAnimationSpeed();
|
||||
}
|
||||
return ret;
|
||||
return static_cast<u32>(ret);
|
||||
}
|
||||
|
||||
void Engine::run()
|
||||
|
|
4
Engine.h
4
Engine.h
|
@ -68,10 +68,13 @@ private:
|
|||
public:
|
||||
std::wstring m_PreviousPath;
|
||||
std::wstring m_PrevTexturePath;
|
||||
irr::f32 axisLength;
|
||||
bool m_zUp;
|
||||
|
||||
Engine();
|
||||
~Engine();
|
||||
|
||||
irr::core::vector3df camTarget();
|
||||
void run();
|
||||
void loadMesh(const std::wstring& fileName);
|
||||
void reloadMesh();
|
||||
|
@ -83,6 +86,7 @@ public:
|
|||
void pauseAnimation();
|
||||
void toggleAnimation();
|
||||
void setAnimationFPS(irr::u32 animationFPS);
|
||||
void incrementAnimationFPS(irr::f32 by);
|
||||
void setZUp(bool zUp);
|
||||
irr::u32 animationFPS();
|
||||
};
|
||||
|
|
|
@ -42,6 +42,7 @@ bool EventHandler::OnEvent(const SEvent& event)
|
|||
} else if (event.EventType == EET_USER_EVENT) {
|
||||
if (event.UserEvent.UserData1 == UEI_WINDOWSIZECHANGED) {
|
||||
// Window resize handling - send to all subscribers
|
||||
// (UserInterface will call snapWidgets to fix playbackWindow position)
|
||||
map<EventReceiverType, IEventReceiver*>::iterator iter;
|
||||
for (iter = m_EventReceivers->begin(); iter != m_EventReceivers->end(); iter++)
|
||||
iter->second->OnEvent(event);
|
||||
|
|
24
README.md
24
README.md
|
@ -117,25 +117,27 @@ only applies to Visual Studio users.)
|
|||
file. However, the program is much easier to use if you associate the
|
||||
format with b3view (see "Installation" above) so you can just double-
|
||||
click the file to open b3view automatically.
|
||||
* `-` / `+`: To change animation frame rate in increments of 5 fps,
|
||||
click "Faster" or "Slower," or use `-` key or `+`/`=` key. By default,
|
||||
the scene refreshes at 60fps and the animation runs as 30 fps
|
||||
(Irrlicht does interpolation automatically).
|
||||
* `t` / `e`: cycle through textures in `../textures` using `t` key (`e`
|
||||
to go back) such as for Minetest mods, where model must be in
|
||||
`modname/models/` and texture must be in `modname/textures/`.
|
||||
* `Ctrl left` / `Ctrl right` (arrow keys) to change animation frame rate
|
||||
in increments of 5 fps, click "Faster" or "Slower," or use `-` key or
|
||||
`+`/`=` key. By default, the scene refreshes at 60fps and the
|
||||
animation runs as 30 fps (Irrlicht does interpolation automatically).
|
||||
Edit the frame rate manually using the input box under "Faster" and
|
||||
"Slower."
|
||||
* `F3` / `Shift F3`: cycle through textures in `../textures` using `F3`
|
||||
key (`Shift` to go backward) such as for Minetest mods, where model
|
||||
must be in `modname/models/` and texture must be in `modname/textures/`.
|
||||
- If `"../textures/" + basename(modelName) + ".png"` or `".jpg"` is
|
||||
present, pressing `t` for the first time will load it.
|
||||
present, pressing `t` for the first time will load it.
|
||||
- If `../textures` doesn't exist relative to the model file's
|
||||
directory, the model file's own directory will be used.
|
||||
* `x`: toggle texture interpolation (shortcut for View, Texture
|
||||
* `Ctrl i`: toggle texture interpolation (shortcut for View, Texture
|
||||
Interpolation)
|
||||
* `F5`: Reload last model file
|
||||
* `r`: Reload last texture file (may not be working due to caching,
|
||||
* `Shift F5`: Reload last texture file (may not be working due to caching,
|
||||
but does try to load different file if texture edit box changed).
|
||||
* drag with middle button: rotate view
|
||||
* drag with middle button while holding shift key: pan up and down
|
||||
* `z` or `y`: change camera "up" axis to Z or Y (Y is default;
|
||||
* View, choose "Up" axis: change camera "up" axis to Z or Y (Y is default;
|
||||
automatically changed to Z when 3ds file is loaded)
|
||||
|
||||
## Known Issues
|
||||
|
|
|
@ -35,15 +35,24 @@ void UserInterface::setupUserInterface()
|
|||
|
||||
// File Menu
|
||||
fileMenu = menu->getSubMenu(0);
|
||||
fileMenu->addItem(L"Load", UIC_FILE_LOAD);
|
||||
fileMenu->addItem(L"LoadTexture", UIC_FILE_LOAD_TEXTURE);
|
||||
fileMenu->addItem(L"Open", UIC_FILE_OPEN);
|
||||
fileMenu->addItem(L"Change Texture", UIC_FILE_OPEN_TEXTURE);
|
||||
fileMenu->addItem(L"Previous Texture Shift F3", UIC_FILE_PREVIOUS_TEXTURE);
|
||||
fileMenu->addItem(L"Next Texture F3", UIC_FILE_NEXT_TEXTURE);
|
||||
fileMenu->addItem(L"Quit", UIC_FILE_QUIT);
|
||||
|
||||
// View Menu
|
||||
viewMenu = menu->getSubMenu(1);
|
||||
INDEX_VIEW_WIREFRAME_MESH = viewMenu->addItem(L"Wireframe Mesh", UIC_VIEW_WIREFRAME, true, false, this->m_WireframeDisplay, true);
|
||||
INDEX_VIEW_LIGHTING = viewMenu->addItem(L"Lighting", UIC_VIEW_LIGHTING, true, false, this->m_Lighting, true);
|
||||
INDEX_VIEW_TEXTURE_INTERPOLATION = viewMenu->addItem(L"Texture Interpolation", UIC_VIEW_TEXTURE_INTERPOLATION, true, false, this->m_TextureInterpolation, true);
|
||||
viewWireframeIdx = viewMenu->addItem(L"Wireframe", UIC_VIEW_WIREFRAME, true, false, this->m_WireframeDisplay, true);
|
||||
viewLightingIdx = viewMenu->addItem(L"Lighting", UIC_VIEW_LIGHTING, true, false, this->m_Lighting, true);
|
||||
viewTargetIdx = viewMenu->addItem(L"Camera Target", UIC_VIEW_TARGET, true, false, true, true);
|
||||
|
||||
viewTextureInterpolationIdx = viewMenu->addItem(L"Texture Interpolation Ctrl i", UIC_VIEW_TEXTURE_INTERPOLATION, true, false, this->m_TextureInterpolation, true);
|
||||
|
||||
viewYUpIdx = viewMenu->addItem(L"Y Up", UIC_VIEW_Y_UP, true, false, true, true);
|
||||
viewZUpIdx = viewMenu->addItem(L"Z Up", UIC_VIEW_Z_UP, true, false, false, true);
|
||||
viewMenu->addItem(L"Slower Ctrl Left", UIC_VIEW_SLOWER, true, false, false, false);
|
||||
viewMenu->addItem(L"Faster Ctrl Right", UIC_VIEW_FASTER, true, false, false, false);
|
||||
|
||||
// Playback Control Window
|
||||
dimension2d<u32> windowSize = m_Engine->m_Driver->getScreenSize();
|
||||
|
@ -51,6 +60,7 @@ void UserInterface::setupUserInterface()
|
|||
rect<s32>(vector2d<s32>(windowSize.Width - 4 - 160, 28), dimension2d<s32>(160, 300)), false, L"Playback", nullptr, UIE_PLAYBACKWINDOW);
|
||||
playbackWindow->getCloseButton()->setVisible(false);
|
||||
s32 spacing_x = 4;
|
||||
s32 margin_y = 4;
|
||||
spacing_y = 4;
|
||||
s32 size_x = playbackWindow->getClientRect().getWidth() - 8;
|
||||
s32 size_y = 24;
|
||||
|
@ -61,6 +71,16 @@ void UserInterface::setupUserInterface()
|
|||
UIE_PLAYBACKSTARTSTOPBUTTON,
|
||||
L"Start/Stop",
|
||||
nullptr);
|
||||
|
||||
y += size_y + spacing_y;
|
||||
playbackSetFrameEditBox = m_Gui->addEditBox(
|
||||
L"",
|
||||
rect<s32>(vector2d<s32>(spacing_x, y), dimension2d<s32>(size_x, size_y)),
|
||||
true,
|
||||
playbackWindow,
|
||||
UIE_PLAYBACKSETFRAMEEDITBOX);
|
||||
y += margin_y;
|
||||
|
||||
y += size_y + spacing_y;
|
||||
playbackIncreaseButton = m_Gui->addButton(
|
||||
rect<s32>(vector2d<s32>(spacing_x, y), dimension2d<s32>(size_x, size_y)),
|
||||
|
@ -68,6 +88,7 @@ void UserInterface::setupUserInterface()
|
|||
UIE_PLAYBACKINCREASEBUTTON,
|
||||
L"Faster",
|
||||
nullptr);
|
||||
|
||||
y += size_y + spacing_y;
|
||||
playbackDecreaseButton = m_Gui->addButton(
|
||||
rect<s32>(vector2d<s32>(spacing_x, y), dimension2d<s32>(size_x, size_y)),
|
||||
|
@ -77,12 +98,13 @@ void UserInterface::setupUserInterface()
|
|||
nullptr);
|
||||
|
||||
y += size_y + spacing_y;
|
||||
playbackSetFrameEditBox = m_Gui->addEditBox(
|
||||
playbackFPSEditBox = m_Gui->addEditBox(
|
||||
L"",
|
||||
rect<s32>(vector2d<s32>(spacing_x, y), dimension2d<s32>(size_x, size_y)),
|
||||
true,
|
||||
playbackWindow,
|
||||
UIE_PLAYBACKSETFRAMEEDITBOX);
|
||||
UIE_FPSEDITBOX);
|
||||
y += margin_y;
|
||||
|
||||
y += size_y + spacing_y;
|
||||
texturePathStaticText = m_Gui->addStaticText(
|
||||
|
@ -93,6 +115,7 @@ void UserInterface::setupUserInterface()
|
|||
playbackWindow,
|
||||
UIE_TEXTUREPATHSTATICTEXT,
|
||||
false);
|
||||
|
||||
y += size_y + spacing_y;
|
||||
texturePathEditBox = m_Gui->addEditBox(
|
||||
L"",
|
||||
|
@ -100,6 +123,28 @@ void UserInterface::setupUserInterface()
|
|||
true,
|
||||
playbackWindow,
|
||||
UIE_TEXTUREPATHEDITBOX);
|
||||
y += margin_y;
|
||||
|
||||
y += size_y + spacing_y;
|
||||
axisSizeStaticText = m_Gui->addStaticText(
|
||||
L"Axis Size:",
|
||||
rect<s32>(vector2d<s32>(spacing_x, y), dimension2d<s32>(size_x, size_y)),
|
||||
true,
|
||||
true,
|
||||
playbackWindow,
|
||||
UIE_AXISSIZESTATICTEXT,
|
||||
false);
|
||||
|
||||
y += size_y + spacing_y;
|
||||
axisSizeEditBox = m_Gui->addEditBox(
|
||||
L"",
|
||||
rect<s32>(vector2d<s32>(spacing_x, y), dimension2d<s32>(size_x, size_y)),
|
||||
true,
|
||||
playbackWindow,
|
||||
UIE_AXISSIZEEDITBOX);
|
||||
y += margin_y;
|
||||
|
||||
y += size_y + spacing_y;
|
||||
|
||||
// Set Font for UI Elements
|
||||
m_GuiFontFace = new CGUITTFace();
|
||||
|
@ -156,30 +201,52 @@ void UserInterface::handleMenuItemPressed(IGUIContextMenu* menu)
|
|||
s32 id = menu->getItemCommandId(static_cast<u32>(selected));
|
||||
|
||||
switch (id) {
|
||||
case UIC_FILE_LOAD:
|
||||
case UIC_FILE_OPEN:
|
||||
displayLoadFileDialog();
|
||||
break;
|
||||
|
||||
case UIC_FILE_LOAD_TEXTURE:
|
||||
case UIC_FILE_OPEN_TEXTURE:
|
||||
displayLoadTextureDialog();
|
||||
break;
|
||||
|
||||
case UIC_FILE_PREVIOUS_TEXTURE:
|
||||
loadNextTexture(-1);
|
||||
break;
|
||||
|
||||
case UIC_FILE_NEXT_TEXTURE:
|
||||
loadNextTexture(1);
|
||||
break;
|
||||
|
||||
case UIC_FILE_QUIT:
|
||||
m_Engine->m_RunEngine = false;
|
||||
break;
|
||||
|
||||
case UIC_VIEW_WIREFRAME:
|
||||
m_WireframeDisplay = viewMenu->isItemChecked(INDEX_VIEW_WIREFRAME_MESH);
|
||||
m_WireframeDisplay = viewMenu->isItemChecked(viewWireframeIdx);
|
||||
m_Engine->setMeshDisplayMode(m_WireframeDisplay, m_Lighting, m_TextureInterpolation);
|
||||
break;
|
||||
|
||||
case UIC_VIEW_LIGHTING:
|
||||
m_Lighting = viewMenu->isItemChecked(INDEX_VIEW_LIGHTING);
|
||||
m_Lighting = viewMenu->isItemChecked(viewLightingIdx);
|
||||
m_Engine->setMeshDisplayMode(m_WireframeDisplay, m_Lighting, m_TextureInterpolation);
|
||||
break;
|
||||
|
||||
case UIC_VIEW_TARGET:
|
||||
//
|
||||
break;
|
||||
|
||||
case UIC_VIEW_Y_UP:
|
||||
m_Engine->setZUp(false);
|
||||
viewMenu->setItemChecked(viewZUpIdx, false);
|
||||
break;
|
||||
|
||||
case UIC_VIEW_Z_UP:
|
||||
m_Engine->setZUp(true);
|
||||
viewMenu->setItemChecked(viewYUpIdx, false);
|
||||
break;
|
||||
|
||||
case UIC_VIEW_TEXTURE_INTERPOLATION:
|
||||
m_TextureInterpolation = viewMenu->isItemChecked(INDEX_VIEW_TEXTURE_INTERPOLATION);
|
||||
m_TextureInterpolation = viewMenu->isItemChecked(viewTextureInterpolationIdx);
|
||||
m_Engine->setMeshDisplayMode(m_WireframeDisplay, m_Lighting, m_TextureInterpolation);
|
||||
break;
|
||||
}
|
||||
|
@ -210,9 +277,9 @@ void UserInterface::snapWidgets()
|
|||
// PUBLIC
|
||||
UserInterface::UserInterface(Engine* engine)
|
||||
{
|
||||
INDEX_VIEW_TEXTURE_INTERPOLATION = 0;
|
||||
INDEX_VIEW_WIREFRAME_MESH = 0;
|
||||
INDEX_VIEW_LIGHTING = 0;
|
||||
viewTextureInterpolationIdx = 0;
|
||||
viewWireframeIdx = 0;
|
||||
viewLightingIdx = 0;
|
||||
this->playbackStartStopButton = nullptr;
|
||||
|
||||
m_Engine = engine;
|
||||
|
@ -286,7 +353,6 @@ bool UserInterface::loadNextTexture(int direction)
|
|||
// debug() << "tryPath 1b " << Utility::toString(tryPath) << "..." << endl;
|
||||
// tryPath = texturesPath + dirSeparator + Utility::basename(this->m_Engine->m_PreviousPath) + L".png";
|
||||
if (!Utility::isFile(tryPath)) {
|
||||
//asdf
|
||||
tryPath = texturesPath + dirSeparator + Utility::withoutExtension(Utility::basename(this->m_Engine->m_PreviousPath)) + L".jpg";
|
||||
// debug() << "tryPath 2a " << Utility::toString(tryPath) << "..." << endl;
|
||||
tryPath = Utility::toWstring(Utility::toString(tryPath));
|
||||
|
@ -305,8 +371,8 @@ bool UserInterface::loadNextTexture(int direction)
|
|||
}
|
||||
}
|
||||
}
|
||||
//debug() << "tryPath: " << Utility::toString(tryPath) << endl;
|
||||
//debug() << "nextPath: " << Utility::toString(nextPath) << endl;
|
||||
// debug() << "tryPath: " << Utility::toString(tryPath) << endl;
|
||||
// debug() << "nextPath: " << Utility::toString(nextPath) << endl;
|
||||
for (const auto& itr : fs::directory_iterator(path)) {
|
||||
std::wstring ext = Utility::extensionOf(itr.path().wstring()); // no dot!
|
||||
if (!is_directory(itr.status())
|
||||
|
@ -346,40 +412,128 @@ bool UserInterface::loadNextTexture(int direction)
|
|||
bool UserInterface::OnEvent(const SEvent& event)
|
||||
{
|
||||
// Events arriving here should be destined for us
|
||||
bool handled = false;
|
||||
if (event.EventType == EET_USER_EVENT) {
|
||||
// debug() << "EET_USER_EVENT..." << endl;
|
||||
if (event.UserEvent.UserData1 == UEI_WINDOWSIZECHANGED) {
|
||||
if ((m_WindowSize.Width != m_Engine->m_Driver->getScreenSize().Width) || (m_WindowSize.Height != m_Engine->m_Driver->getScreenSize().Height)) {
|
||||
snapWidgets();
|
||||
}
|
||||
handled = true;
|
||||
}
|
||||
} else if (event.EventType == EET_GUI_EVENT) {
|
||||
// debug() << "EET_GUI_EVENT..." << endl;
|
||||
handled = true; // set to false below if not handled
|
||||
const SEvent::SGUIEvent* ge = &(event.GUIEvent);
|
||||
switch (ge->Caller->getID()) {
|
||||
case UIE_FILEMENU:
|
||||
case UIE_VIEWMENU:
|
||||
// call handler for all menu related actions
|
||||
handleMenuItemPressed(static_cast<IGUIContextMenu*>(ge->Caller));
|
||||
break;
|
||||
|
||||
case UIE_LOADFILEDIALOG:
|
||||
if (ge->EventType == EGET_FILE_SELECTED) {
|
||||
IGUIFileOpenDialog* fileOpenDialog = static_cast<IGUIFileOpenDialog*>(ge->Caller);
|
||||
m_Engine->loadMesh(fileOpenDialog->getFileName());
|
||||
}
|
||||
break;
|
||||
|
||||
case UIE_LOADTEXTUREDIALOG:
|
||||
if (ge->EventType == EGET_FILE_SELECTED) {
|
||||
IGUIFileOpenDialog* fileOpenDialog = static_cast<IGUIFileOpenDialog*>(ge->Caller);
|
||||
m_Engine->loadTexture(fileOpenDialog->getFileName());
|
||||
}
|
||||
break;
|
||||
|
||||
case UIE_PLAYBACKSTARTSTOPBUTTON:
|
||||
if (ge->EventType == EGET_BUTTON_CLICKED) {
|
||||
this->m_Engine->toggleAnimation();
|
||||
}
|
||||
break;
|
||||
|
||||
case UIE_PLAYBACKINCREASEBUTTON:
|
||||
if (ge->EventType == EGET_BUTTON_CLICKED) {
|
||||
this->m_Engine->incrementAnimationFPS(5);
|
||||
}
|
||||
break;
|
||||
|
||||
case UIE_PLAYBACKDECREASEBUTTON:
|
||||
if (ge->EventType == EGET_BUTTON_CLICKED) {
|
||||
this->m_Engine->incrementAnimationFPS(-5);
|
||||
}
|
||||
break;
|
||||
case UIE_PLAYBACKSETFRAMEEDITBOX:
|
||||
if (ge->EventType == EGET_EDITBOX_ENTER) {
|
||||
if (this->m_Engine->m_LoadedMesh != nullptr) {
|
||||
this->m_Engine->m_LoadedMesh->setCurrentFrame(Utility::toF32(this->playbackSetFrameEditBox->getText()));
|
||||
}
|
||||
}
|
||||
break;
|
||||
case UIE_TEXTUREPATHEDITBOX:
|
||||
if (ge->EventType == EGET_EDITBOX_ENTER) {
|
||||
if (this->m_Engine->m_LoadedMesh != nullptr) {
|
||||
this->m_Engine->loadTexture(texturePathEditBox->getText());
|
||||
}
|
||||
}
|
||||
break;
|
||||
case UIE_FPSEDITBOX:
|
||||
if (ge->EventType == EGET_EDITBOX_ENTER) {
|
||||
if (this->m_Engine->m_LoadedMesh != nullptr) {
|
||||
this->m_Engine->m_LoadedMesh->setAnimationSpeed(Utility::toF32(this->playbackFPSEditBox->getText()));
|
||||
}
|
||||
}
|
||||
break;
|
||||
case UIE_AXISSIZEEDITBOX:
|
||||
if (ge->EventType == EGET_EDITBOX_ENTER) {
|
||||
this->m_Engine->axisLength = Utility::toF32(this->axisSizeEditBox->getText());
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
// break;
|
||||
handled = false;
|
||||
}
|
||||
return true;
|
||||
} else if (event.EventType == EET_KEY_INPUT_EVENT) {
|
||||
// debug() << "EET_KEY_INPUT_EVENT..." << endl;
|
||||
handled = true; // set to false below if not handled
|
||||
if (event.KeyInput.PressedDown && !m_Engine->KeyIsDown[event.KeyInput.Key]) {
|
||||
if (event.KeyInput.Key == irr::KEY_F5) {
|
||||
m_Engine->reloadMesh();
|
||||
} else if (event.KeyInput.Key == irr::KEY_KEY_T) {
|
||||
loadNextTexture(1);
|
||||
} else if (event.KeyInput.Key == irr::KEY_KEY_E) {
|
||||
loadNextTexture(-1);
|
||||
} else if (event.KeyInput.Key == irr::KEY_KEY_R) {
|
||||
m_Engine->reloadTexture();
|
||||
} else if (event.KeyInput.Key == irr::KEY_KEY_Z) {
|
||||
m_Engine->setZUp(true);
|
||||
} else if (event.KeyInput.Key == irr::KEY_KEY_Y) {
|
||||
m_Engine->setZUp(false);
|
||||
} else if (event.KeyInput.Key == irr::KEY_KEY_X) {
|
||||
// IGUIContextMenu* textureInterpolationElement = dynamic_cast<IGUIContextMenu*>(viewMenu->getElementFromId(UIC_VIEW_TEXTURE_INTERPOLATION));
|
||||
//m_TextureInterpolation = textureInterpolationElement->isItemChecked(UIC_VIEW_TEXTURE_INTERPOLATION);
|
||||
m_TextureInterpolation = m_TextureInterpolation ? false : true;
|
||||
//doesn't work: m_TextureInterpolation = viewMenu->isItemChecked(UIC_VIEW_TEXTURE_INTERPOLATION);
|
||||
m_Engine->setMeshDisplayMode(m_WireframeDisplay, m_Lighting, m_TextureInterpolation);
|
||||
viewMenu->setItemChecked(INDEX_VIEW_TEXTURE_INTERPOLATION, m_TextureInterpolation);
|
||||
} else if (event.KeyInput.Char == L'+' || event.KeyInput.Char == L'=') {
|
||||
m_Engine->setAnimationFPS(m_Engine->animationFPS() + 5);
|
||||
} else if (event.KeyInput.Char == L'-') {
|
||||
if (m_Engine->animationFPS() > 0) {
|
||||
m_Engine->setAnimationFPS(m_Engine->animationFPS() - 5);
|
||||
if (m_Engine->KeyIsDown[irr::KEY_LSHIFT] || m_Engine->KeyIsDown[irr::KEY_RSHIFT]) {
|
||||
m_Engine->reloadTexture();
|
||||
}
|
||||
else
|
||||
m_Engine->reloadMesh();
|
||||
} else if (event.KeyInput.Key == irr::KEY_F3) {
|
||||
if (m_Engine->KeyIsDown[irr::KEY_LSHIFT] || m_Engine->KeyIsDown[irr::KEY_RSHIFT]) {
|
||||
loadNextTexture(-1);
|
||||
debug() << " - back" << endl;
|
||||
}
|
||||
else
|
||||
loadNextTexture(1);
|
||||
} else if (event.KeyInput.Key == irr::KEY_KEY_I) {
|
||||
if (m_Engine->KeyIsDown[irr::KEY_LCONTROL] || m_Engine->KeyIsDown[irr::KEY_RCONTROL]) {
|
||||
// IGUIContextMenu* textureInterpolationElement = dynamic_cast<IGUIContextMenu*>(viewMenu->getElementFromId(UIC_VIEW_TEXTURE_INTERPOLATION));
|
||||
// m_TextureInterpolation = textureInterpolationElement->isItemChecked(UIC_VIEW_TEXTURE_INTERPOLATION);
|
||||
m_TextureInterpolation = m_TextureInterpolation ? false : true;
|
||||
// doesn't work: m_TextureInterpolation = viewMenu->isItemChecked(UIC_VIEW_TEXTURE_INTERPOLATION);
|
||||
m_Engine->setMeshDisplayMode(m_WireframeDisplay, m_Lighting, m_TextureInterpolation);
|
||||
viewMenu->setItemChecked(viewTextureInterpolationIdx, m_TextureInterpolation);
|
||||
}
|
||||
else
|
||||
handled = false;
|
||||
} else if (event.KeyInput.Key == irr::KEY_RIGHT) {
|
||||
if (m_Engine->KeyIsDown[irr::KEY_LCONTROL] || m_Engine->KeyIsDown[irr::KEY_RCONTROL]) {
|
||||
m_Engine->incrementAnimationFPS(5);
|
||||
}
|
||||
else
|
||||
handled = false;
|
||||
} else if (event.KeyInput.Key == irr::KEY_LEFT) {
|
||||
if (m_Engine->KeyIsDown[irr::KEY_LCONTROL] || m_Engine->KeyIsDown[irr::KEY_RCONTROL]) {
|
||||
m_Engine->incrementAnimationFPS(-5);
|
||||
}
|
||||
else
|
||||
handled = false;
|
||||
} else if (event.KeyInput.Char == L' ') {
|
||||
m_Engine->toggleAnimation();
|
||||
} else if (event.KeyInput.Key == irr::KEY_LEFT) {
|
||||
|
@ -397,13 +551,18 @@ bool UserInterface::OnEvent(const SEvent& event)
|
|||
this->playbackSetFrameEditBox->setText(Utility::toWstring(this->m_Engine->m_LoadedMesh->getFrameNr()).c_str());
|
||||
}
|
||||
}
|
||||
else
|
||||
handled = false;
|
||||
// std::wcerr << "Char: " << event.KeyInput.Char << endl;
|
||||
}
|
||||
m_Engine->KeyIsDown[event.KeyInput.Key] = event.KeyInput.PressedDown;
|
||||
|
||||
return true;
|
||||
} else if (event.EventType == EET_MOUSE_INPUT_EVENT) {
|
||||
// TODO: improve this copypasta
|
||||
// debug() << "EET_MOUSE_INPUT_EVENT..." << endl;
|
||||
handled = true; // set to false below if not handled
|
||||
// TODO: improve this copypasta (or elsewhere use states 1 and 3 as
|
||||
// events, and add 1 as "handled" (or set back to 0 for no drag feature)
|
||||
// as intended for drag or long press handling).
|
||||
switch (event.MouseInput.Event) {
|
||||
case EMIE_LMOUSE_LEFT_UP:
|
||||
if (m_Engine->LMouseState == 2) {
|
||||
|
@ -428,63 +587,9 @@ bool UserInterface::OnEvent(const SEvent& event)
|
|||
m_Engine->RMouseState = 1;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
handled = false;
|
||||
}
|
||||
} else if (!(event.EventType == EET_GUI_EVENT))
|
||||
return false;
|
||||
|
||||
const SEvent::SGUIEvent* ge = &(event.GUIEvent);
|
||||
|
||||
switch (ge->Caller->getID()) {
|
||||
case UIE_FILEMENU:
|
||||
case UIE_VIEWMENU:
|
||||
// call handler for all menu related actions
|
||||
handleMenuItemPressed(static_cast<IGUIContextMenu*>(ge->Caller));
|
||||
break;
|
||||
|
||||
case UIE_LOADFILEDIALOG:
|
||||
if (ge->EventType == EGET_FILE_SELECTED) {
|
||||
IGUIFileOpenDialog* fileOpenDialog = static_cast<IGUIFileOpenDialog*>(ge->Caller);
|
||||
m_Engine->loadMesh(fileOpenDialog->getFileName());
|
||||
}
|
||||
break;
|
||||
|
||||
case UIE_LOADTEXTUREDIALOG:
|
||||
if (ge->EventType == EGET_FILE_SELECTED) {
|
||||
IGUIFileOpenDialog* fileOpenDialog = static_cast<IGUIFileOpenDialog*>(ge->Caller);
|
||||
m_Engine->loadTexture(fileOpenDialog->getFileName());
|
||||
}
|
||||
break;
|
||||
|
||||
case UIE_PLAYBACKSTARTSTOPBUTTON:
|
||||
if (ge->EventType == EGET_BUTTON_CLICKED) {
|
||||
this->m_Engine->toggleAnimation();
|
||||
}
|
||||
break;
|
||||
|
||||
case UIE_PLAYBACKINCREASEBUTTON:
|
||||
if (ge->EventType == EGET_BUTTON_CLICKED) {
|
||||
this->m_Engine->setAnimationFPS(this->m_Engine->animationFPS() + 5);
|
||||
}
|
||||
break;
|
||||
|
||||
case UIE_PLAYBACKDECREASEBUTTON:
|
||||
if (ge->EventType == EGET_BUTTON_CLICKED) {
|
||||
if (this->m_Engine->animationFPS() >= 5) {
|
||||
this->m_Engine->setAnimationFPS(this->m_Engine->animationFPS() - 5);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case UIE_PLAYBACKSETFRAMEEDITBOX:
|
||||
if (ge->EventType == EGET_EDITBOX_ENTER) {
|
||||
if (this->m_Engine->m_LoadedMesh != nullptr) {
|
||||
this->m_Engine->m_LoadedMesh->setCurrentFrame(Utility::toF32(this->playbackSetFrameEditBox->getText()));
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
return handled;
|
||||
}
|
||||
|
|
|
@ -17,20 +17,30 @@ enum UserInterfaceElements {
|
|||
|
||||
UIE_PLAYBACKWINDOW = 3000,
|
||||
UIE_PLAYBACKSTARTSTOPBUTTON = 3001,
|
||||
UIE_PLAYBACKINCREASEBUTTON = 3002,
|
||||
UIE_PLAYBACKDECREASEBUTTON = 3003,
|
||||
UIE_PLAYBACKSETFRAMEEDITBOX = 3004,
|
||||
UIE_TEXTUREPATHSTATICTEXT = 3005,
|
||||
UIE_TEXTUREPATHEDITBOX = 3006
|
||||
UIE_PLAYBACKSETFRAMEEDITBOX = 3002,
|
||||
UIE_PLAYBACKINCREASEBUTTON = 3003,
|
||||
UIE_PLAYBACKDECREASEBUTTON = 3004,
|
||||
UIE_FPSEDITBOX = 3005,
|
||||
UIE_TEXTUREPATHSTATICTEXT = 3006,
|
||||
UIE_TEXTUREPATHEDITBOX = 3007,
|
||||
UIE_AXISSIZESTATICTEXT = 3008,
|
||||
UIE_AXISSIZEEDITBOX = 3009
|
||||
};
|
||||
|
||||
enum UserInterfaceCommands {
|
||||
UIC_FILE_LOAD = 1000,
|
||||
UIC_FILE_OPEN = 1000,
|
||||
UIC_FILE_QUIT = 1001,
|
||||
UIC_FILE_LOAD_TEXTURE = 1002,
|
||||
UIC_FILE_OPEN_TEXTURE = 1002,
|
||||
UIC_FILE_NEXT_TEXTURE = 1003,
|
||||
UIC_FILE_PREVIOUS_TEXTURE = 1004,
|
||||
UIC_VIEW_WIREFRAME = 2001,
|
||||
UIC_VIEW_LIGHTING = 2002,
|
||||
UIC_VIEW_TEXTURE_INTERPOLATION = 2003
|
||||
UIC_VIEW_TARGET = 2003,
|
||||
UIC_VIEW_TEXTURE_INTERPOLATION = 2004,
|
||||
UIC_VIEW_Y_UP = 2005,
|
||||
UIC_VIEW_Z_UP = 2006,
|
||||
UIC_VIEW_SLOWER = 2007,
|
||||
UIC_VIEW_FASTER = 2008
|
||||
};
|
||||
|
||||
class UserInterface : public irr::IEventReceiver {
|
||||
|
@ -56,14 +66,20 @@ public:
|
|||
irr::gui::IGUIContextMenu* fileMenu;
|
||||
irr::gui::IGUIContextMenu* viewMenu;
|
||||
irr::gui::IGUIButton* playbackStartStopButton;
|
||||
irr::gui::IGUIEditBox* playbackSetFrameEditBox;
|
||||
irr::gui::IGUIButton* playbackIncreaseButton;
|
||||
irr::gui::IGUIButton* playbackDecreaseButton;
|
||||
irr::gui::IGUIEditBox* playbackSetFrameEditBox;
|
||||
irr::gui::IGUIEditBox* playbackFPSEditBox;
|
||||
irr::gui::IGUIStaticText* texturePathStaticText;
|
||||
irr::gui::IGUIEditBox* texturePathEditBox;
|
||||
irr::u32 INDEX_VIEW_TEXTURE_INTERPOLATION;
|
||||
irr::u32 INDEX_VIEW_WIREFRAME_MESH;
|
||||
irr::u32 INDEX_VIEW_LIGHTING;
|
||||
irr::gui::IGUIStaticText* axisSizeStaticText;
|
||||
irr::gui::IGUIEditBox* axisSizeEditBox;
|
||||
irr::u32 viewTextureInterpolationIdx;
|
||||
irr::u32 viewWireframeIdx;
|
||||
irr::u32 viewLightingIdx;
|
||||
irr::u32 viewTargetIdx;
|
||||
irr::u32 viewYUpIdx;
|
||||
irr::u32 viewZUpIdx;
|
||||
|
||||
void snapWidgets();
|
||||
|
||||
|
|
|
@ -218,6 +218,12 @@ irr::f32 Utility::toF32(wstring val)
|
|||
return ret;
|
||||
}
|
||||
|
||||
irr::f32 Utility::distance(const vector3df &start, const vector3df &end)
|
||||
{
|
||||
vector3df offsetVec3(end.X - start.X, end.Y - start.Y, end.Z - start.Z);
|
||||
return offsetVec3.getLength();
|
||||
}
|
||||
|
||||
bool Utility::isFile(const std::wstring& name)
|
||||
{
|
||||
std::string name_s = toString(name);
|
||||
|
|
|
@ -24,6 +24,7 @@ public:
|
|||
static std::wstring toWstring(int val);
|
||||
static std::wstring toWstring(const std::string& str);
|
||||
static irr::f32 toF32(std::wstring val);
|
||||
static irr::f32 distance(const irr::core::vector3df& start, const irr::core::vector3df& end);
|
||||
// compiler doesn't like template function when class is not a template--instantiate immediately
|
||||
// see http://processors.wiki.ti.com/index.php/C%2B%2B_Template_Instantiation_Issues
|
||||
template <typename T>
|
||||
|
|
165
View.cpp
165
View.cpp
|
@ -2,6 +2,8 @@
|
|||
#include "Engine.h"
|
||||
#include <iostream>
|
||||
|
||||
#include "Utility.h"
|
||||
|
||||
using namespace irr;
|
||||
using namespace irr::core;
|
||||
using namespace irr::scene;
|
||||
|
@ -43,16 +45,15 @@ void View::setNewCameraPosition(bool zUp)
|
|||
}
|
||||
if (zUp) {
|
||||
newCameraPosition.X = 0;
|
||||
newCameraPosition.Y = m_CameraDistance * cos(m_Pitch);
|
||||
newCameraPosition.Z = m_CameraDistance * sin(m_Pitch);
|
||||
yawMatrix.setRotationRadians(vector3df(0, 0, m_Yaw));
|
||||
newCameraPosition.Y = m_CameraDistance * cos(m_PitchFromTarget);
|
||||
newCameraPosition.Z = m_CameraDistance * sin(m_PitchFromTarget);
|
||||
yawMatrix.setRotationRadians(vector3df(0, 0, m_YawFromTarget));
|
||||
} else {
|
||||
newCameraPosition.X = 0;
|
||||
newCameraPosition.Y = m_CameraDistance * sin(m_Pitch);
|
||||
newCameraPosition.Z = m_CameraDistance * cos(m_Pitch);
|
||||
yawMatrix.setRotationRadians(vector3df(0, m_Yaw, 0));
|
||||
newCameraPosition.Y = m_CameraDistance * sin(m_PitchFromTarget);
|
||||
newCameraPosition.Z = m_CameraDistance * cos(m_PitchFromTarget);
|
||||
yawMatrix.setRotationRadians(vector3df(0, m_YawFromTarget, 0));
|
||||
}
|
||||
|
||||
yawMatrix.transformVect(newCameraPosition);
|
||||
|
||||
if (zUp) {
|
||||
|
@ -68,17 +69,17 @@ void View::setNewCameraPosition(bool zUp)
|
|||
camera->setTarget(m_Engine->m_CamTarget);
|
||||
|
||||
// Set Light direction
|
||||
setNewLightDirection(newCameraPosition);
|
||||
setNewLightDirection(newCameraPosition, m_Engine->m_CamTarget);
|
||||
m_zUp = zUp;
|
||||
// std::wcerr << L" setCameraPosition pitch: " << m_Pitch << endl;
|
||||
}
|
||||
|
||||
void View::setNewLightDirection(const vector3df& cameraPosition)
|
||||
void View::setNewLightDirection(const vector3df& cameraPosition, const vector3df& cameraTarget)
|
||||
{
|
||||
ILightSceneNode* light = static_cast<ILightSceneNode*>(m_Engine->m_Scene->getSceneNodeFromId(SIID_LIGHT));
|
||||
|
||||
matrix4 m;
|
||||
m.buildRotateFromTo(vector3df(0, 0, 1), vector3df(cameraPosition).invert().normalize());
|
||||
m.buildRotateFromTo(cameraTarget, vector3df(cameraPosition).invert().normalize());
|
||||
|
||||
light->setRotation(m.getRotationDegrees());
|
||||
}
|
||||
|
@ -90,7 +91,9 @@ View::View(Engine* engine)
|
|||
m_LastMousePosition = new vector2d<int>();
|
||||
m_RotMouse = false;
|
||||
|
||||
m_Pitch = PI;
|
||||
//m_Pitch = PI;
|
||||
|
||||
// Initial camera values: see Engine::setupScene
|
||||
|
||||
// Set Camera Distance
|
||||
// m_CameraDistance = 10;
|
||||
|
@ -110,14 +113,14 @@ View::View(Engine* engine)
|
|||
// see rogerborg on <http://irrlicht.sourceforge.net/forum/viewtopic.php?f=1&t=30477>
|
||||
// const f32 dot = engine->tmpTargetVec3f.dotProduct(engine->tmpPosVec3f); // to...(from) // angle only
|
||||
|
||||
m_Yaw = atan2(offsetVec3.X, offsetVec3.Z);
|
||||
m_Pitch = asin(-offsetVec3.Y);
|
||||
m_YawFromTarget = atan2(offsetVec3.X, offsetVec3.Z);
|
||||
m_PitchFromTarget = asin(offsetVec3.Y);
|
||||
|
||||
// m_Yaw = rotationVec3.Y;
|
||||
// m_Pitch = rotationVec3.X;
|
||||
|
||||
debug() << "Yaw: " << radToDeg(m_Yaw) << endl;
|
||||
debug() << "Pitch: " << radToDeg(m_Pitch) << endl;
|
||||
debug() << "STARTING Yaw: " << radToDeg(m_YawFromTarget)<< " Pitch: " << radToDeg(m_PitchFromTarget) << endl;
|
||||
setNewCameraPosition();
|
||||
}
|
||||
|
||||
View::~View()
|
||||
|
@ -132,6 +135,11 @@ void View::setZUp(bool zUp)
|
|||
}
|
||||
}
|
||||
|
||||
float View::cameraDistance()
|
||||
{
|
||||
return m_CameraDistance;
|
||||
}
|
||||
|
||||
void View::setCameraDistance(float cameraDistance)
|
||||
{
|
||||
m_CameraDistance = cameraDistance;
|
||||
|
@ -139,7 +147,7 @@ void View::setCameraDistance(float cameraDistance)
|
|||
|
||||
bool View::zUp()
|
||||
{
|
||||
return m_zUp;
|
||||
return this->m_zUp;
|
||||
}
|
||||
|
||||
// IEventReceiver
|
||||
|
@ -153,7 +161,7 @@ bool View::OnEvent(const SEvent& event)
|
|||
if (event.EventType == EET_USER_EVENT && event.UserEvent.UserData1 == UEI_WINDOWSIZECHANGED) {
|
||||
dimension2d<u32> windowSize = m_Engine->m_Driver->getScreenSize();
|
||||
f32 aspectRatio = static_cast<f32>(windowSize.Width) / static_cast<f32>(windowSize.Height);
|
||||
debug() << "Setting aspect to: " << aspectRatio << endl;
|
||||
// debug() << "Setting aspect to: " << aspectRatio << endl;
|
||||
m_Engine->m_Scene->getActiveCamera()->setAspectRatio(aspectRatio);
|
||||
}
|
||||
|
||||
|
@ -167,12 +175,41 @@ bool View::OnEvent(const SEvent& event)
|
|||
} else if (mouseEvent->Event == EMIE_MMOUSE_LEFT_UP) {
|
||||
m_RotMouse = false;
|
||||
} else if (mouseEvent->Event == EMIE_MOUSE_WHEEL) {
|
||||
f32 distanceDelta = mouseEvent->Wheel / 2.5f;
|
||||
if (m_CameraDistance - distanceDelta > 0.1f)
|
||||
m_CameraDistance -= distanceDelta;
|
||||
// Zoom camera.
|
||||
//debug() << "Wheel=" << mouseEvent->Wheel; // -1 or 1
|
||||
vector3df offsetVec3(
|
||||
m_Engine->m_CamPos.X - m_Engine->m_CamTarget.X,
|
||||
m_Engine->m_CamPos.Y - m_Engine->m_CamTarget.Y,
|
||||
m_Engine->m_CamPos.Z - m_Engine->m_CamTarget.Z);
|
||||
|
||||
f32 distanceDelta = mouseEvent->Wheel * -1 * (offsetVec3.getLength() / 10);
|
||||
ICameraSceneNode* camera = m_Engine->m_Scene->getActiveCamera();
|
||||
f32 distanceFactor = distanceDelta / Utility::distance(m_Engine->m_CamPos, m_Engine->m_CamTarget);
|
||||
////m_Engine->m_CamPos.interpolate(m_Engine->m_CamPos, m_Engine->m_CamTarget, distanceFactor);
|
||||
////offsetVec3.normalize();
|
||||
//m_Engine->m_CamPos.X -= offsetVec3.X * distanceFactor;
|
||||
//m_Engine->m_CamPos.Y -= offsetVec3.Y * distanceFactor;
|
||||
//m_Engine->m_CamPos.Z -= offsetVec3.Z * distanceFactor;
|
||||
//m_Engine->m_CamTarget.X -= offsetVec3.X * distanceFactor;
|
||||
//m_Engine->m_CamTarget.Y -= offsetVec3.Y * distanceFactor;
|
||||
//m_Engine->m_CamTarget.Z -= offsetVec3.Z * distanceFactor;
|
||||
|
||||
offsetVec3 = vector3df(
|
||||
m_Engine->m_CamPos.X - m_Engine->m_CamTarget.X,
|
||||
m_Engine->m_CamPos.Y - m_Engine->m_CamTarget.Y,
|
||||
m_Engine->m_CamPos.Z - m_Engine->m_CamTarget.Z);
|
||||
//camera->setPosition(m_Engine->m_CamPos);
|
||||
//camera->setTarget(m_Engine->m_CamTarget);
|
||||
|
||||
//m_Yaw = atan2(offsetVec3.X, offsetVec3.Z);
|
||||
//m_Pitch = asin(offsetVec3.Y);
|
||||
|
||||
//m_CameraDistance = Utility::distance(m_Engine->m_CamPos, m_Engine->m_CamTarget);
|
||||
m_CameraDistance += distanceDelta;
|
||||
setNewCameraPosition();
|
||||
debug() << "m_CamPos: " << m_Engine->m_CamPos.X << "," << m_Engine->m_CamPos.Y << " m_CamTarget: " << m_Engine->m_CamTarget.X << "," << m_Engine->m_CamTarget.Y << endl;
|
||||
} else if (m_RotMouse) {
|
||||
// debug() << "Yaw: " << radToDeg(m_Yaw) << " Pitch: " << radToDeg(m_Pitch) << endl;
|
||||
int dx = mouseEvent->X - m_LastMousePosition->X;
|
||||
int dy = mouseEvent->Y - m_LastMousePosition->Y;
|
||||
|
||||
|
@ -180,23 +217,36 @@ bool View::OnEvent(const SEvent& event)
|
|||
m_LastMousePosition->Y = mouseEvent->Y;
|
||||
if (m_Engine->KeyIsDown[irr::KEY_RSHIFT] || m_Engine->KeyIsDown[irr::KEY_LSHIFT]) {
|
||||
// Pan camera.
|
||||
float yDelta = (dy / 400.0f) * m_CameraDistance;
|
||||
float yDelta = (dy / static_cast<float>(m_Engine->m_Driver->getScreenSize().Height/2)) * m_CameraDistance;
|
||||
ICameraSceneNode* camera = m_Engine->m_Scene->getActiveCamera();
|
||||
vector3df rotationVec3;
|
||||
rotationVec3 = camera->getRotation();
|
||||
f32 sidewaysAngle = 0;
|
||||
vector3df target3df = camera->getTarget();
|
||||
vector3df camera3df = camera->getAbsolutePosition();
|
||||
vector2df cameraFromTarget;
|
||||
cameraFromTarget.X = camera3df.X - target3df.X;
|
||||
cameraFromTarget.Y = camera3df.Y - target3df.Y;
|
||||
if (!m_zUp) {
|
||||
// sidewaysAngle = camera->getRotation().Y;
|
||||
cameraFromTarget.Y = camera3df.Z - camera3df.Z;
|
||||
}
|
||||
// sidewaysAngle = camera->getRotation().Z; // always zero for unknown reason
|
||||
// sidewaysAngle = atan2(cameraFromTarget.Y, cameraFromTarget.X);
|
||||
// if (sidewaysAngle > 2 * PI)
|
||||
// sidewaysAngle -= 2 * PI;
|
||||
// vector3df rotationVec3;
|
||||
// rotationVec3 = camera->getRotation();
|
||||
vector3df forwards(0, 0, 1);
|
||||
vector3df dirVec3 = camera->getUpVector();
|
||||
// vector3df camRot = camera->getRotation();
|
||||
vector3df camRot(0, 0, 0);
|
||||
// TODO: fix this (pitch becomes flat)
|
||||
camRot.X = m_Pitch;
|
||||
camRot.X = m_PitchFromTarget;
|
||||
if (m_zUp) {
|
||||
camRot.Z = m_Yaw;
|
||||
camRot.Z = m_YawFromTarget;
|
||||
forwards = vector3df(0, 1, 0);
|
||||
dirVec3.rotateYZBy(camRot.X);
|
||||
dirVec3.rotateXYBy(camRot.Z);
|
||||
} else {
|
||||
camRot.Z = m_Pitch;
|
||||
camRot.Z = m_PitchFromTarget;
|
||||
dirVec3.rotateYZBy(camRot.X);
|
||||
dirVec3.rotateXYBy(camRot.Y);
|
||||
}
|
||||
|
@ -214,6 +264,8 @@ bool View::OnEvent(const SEvent& event)
|
|||
m_Engine->m_CamTarget.X += dirVec3.X;
|
||||
m_Engine->m_CamTarget.Y += dirVec3.Y;
|
||||
m_Engine->m_CamTarget.Z += dirVec3.Z;
|
||||
|
||||
|
||||
if (m_zUp) {
|
||||
//m_Engine->m_CamPos.Z += yDelta;
|
||||
//m_Engine->m_CamTarget.Z += yDelta;
|
||||
|
@ -221,16 +273,51 @@ bool View::OnEvent(const SEvent& event)
|
|||
//m_Engine->m_CamPos.Y += yDelta;
|
||||
//m_Engine->m_CamTarget.Y += yDelta;
|
||||
}
|
||||
camera->setPosition(m_Engine->m_CamPos);
|
||||
camera->setTarget(m_Engine->m_CamTarget);
|
||||
// camera->setPosition(m_Engine->m_CamPos);
|
||||
// camera->setTarget(m_Engine->m_CamTarget);
|
||||
vector3df offsetVec3(
|
||||
m_Engine->m_CamPos.X - m_Engine->m_CamTarget.X,
|
||||
m_Engine->m_CamPos.Y - m_Engine->m_CamTarget.Y,
|
||||
m_Engine->m_CamPos.Z - m_Engine->m_CamTarget.Z);
|
||||
m_CameraDistance = offsetVec3.getLength();
|
||||
m_Engine->m_CamPos.Z - m_Engine->m_CamTarget.Z
|
||||
);
|
||||
|
||||
m_Yaw = atan2(offsetVec3.X, offsetVec3.Z);
|
||||
m_Pitch = asin(-offsetVec3.Y);
|
||||
// m_CameraDistance = offsetVec3.getLength(); //bad: resets zoom
|
||||
|
||||
// m_Yaw = atan2(offsetVec3.X, offsetVec3.Z);
|
||||
// m_Pitch = asin(offsetVec3.Y);
|
||||
setNewCameraPosition();
|
||||
debug() << "AFTER Yaw: " << radToDeg(m_YawFromTarget)<< " Pitch: " << radToDeg(m_PitchFromTarget) << endl;
|
||||
|
||||
float xDelta = (dx / static_cast<float>(m_Engine->m_Driver->getScreenSize().Width/2)) * m_CameraDistance;
|
||||
|
||||
vector3df sidewaysVec3;
|
||||
sidewaysAngle = m_YawFromTarget;
|
||||
// sidewaysAngle += ((PI / 2.0) * 1.0);
|
||||
if (sidewaysAngle > 2 * PI) {
|
||||
sidewaysAngle -= 2 * PI;
|
||||
}
|
||||
else if (sidewaysAngle < -2 * PI) {
|
||||
sidewaysAngle += 2 * PI;
|
||||
}
|
||||
if (sidewaysAngle > PI) {
|
||||
sidewaysAngle = sidewaysAngle - 2 * PI;
|
||||
}
|
||||
sidewaysVec3.X = xDelta * cos(sidewaysAngle);
|
||||
if (m_zUp) {
|
||||
sidewaysVec3.Y = xDelta * sin(sidewaysAngle);
|
||||
sidewaysVec3.Z = 0;
|
||||
}
|
||||
else {
|
||||
sidewaysVec3.Z = xDelta * sin(sidewaysAngle);
|
||||
sidewaysVec3.Y = 0;
|
||||
}
|
||||
debug() << "sidewaysAngle:" << sidewaysAngle << " zUp:" << ((m_zUp)?"true":"false") << endl;
|
||||
m_Engine->m_CamPos.X += sidewaysVec3.X;
|
||||
m_Engine->m_CamPos.Y += sidewaysVec3.Y;
|
||||
m_Engine->m_CamPos.Z += sidewaysVec3.Z;
|
||||
m_Engine->m_CamTarget.X += sidewaysVec3.X;
|
||||
m_Engine->m_CamTarget.Y += sidewaysVec3.Y;
|
||||
m_Engine->m_CamTarget.Z += sidewaysVec3.Z;
|
||||
setNewCameraPosition();
|
||||
} else {
|
||||
// Revolve camera around object.
|
||||
|
@ -239,16 +326,16 @@ bool View::OnEvent(const SEvent& event)
|
|||
// (This old code which may make assumptions about view tends to lock on min/max)
|
||||
// if ((m_Pitch - pitchDelta > (PI - (PI / 2))) && (m_Pitch - pitchDelta < PI + (PI/2)))
|
||||
// m_Pitch -= dy / 120.0f;
|
||||
m_Pitch += pitchDelta;
|
||||
m_PitchFromTarget += pitchDelta;
|
||||
float minPitch = -PI / 2.0f + PI / 1000.0f;
|
||||
float maxPitch = PI / 2.0f - PI / 1000.0f;
|
||||
if (m_Pitch < minPitch)
|
||||
m_Pitch = minPitch;
|
||||
else if (m_Pitch > maxPitch)
|
||||
m_Pitch = maxPitch;
|
||||
if (m_PitchFromTarget < minPitch)
|
||||
m_PitchFromTarget = minPitch;
|
||||
else if (m_PitchFromTarget > maxPitch)
|
||||
m_PitchFromTarget = maxPitch;
|
||||
// std::wcerr << "pitch = " << m_Pitch << endl;
|
||||
|
||||
m_Yaw += dx / 120.0f;
|
||||
m_YawFromTarget += dx / 120.0f;
|
||||
|
||||
// Set Camera to new rotation
|
||||
setNewCameraPosition();
|
||||
|
|
5
View.h
5
View.h
|
@ -8,19 +8,20 @@ class Engine;
|
|||
class View : public irr::IEventReceiver {
|
||||
private:
|
||||
Engine* m_Engine;
|
||||
irr::f32 m_Yaw, m_Pitch, m_CameraDistance;
|
||||
irr::f32 m_YawFromTarget, m_PitchFromTarget, m_CameraDistance;
|
||||
irr::core::vector2d<int>* m_LastMousePosition;
|
||||
bool m_RotMouse;
|
||||
bool m_zUp;
|
||||
|
||||
void setNewCameraPosition();
|
||||
void setNewCameraPosition(bool zUp);
|
||||
void setNewLightDirection(const irr::core::vector3df& cameraPosition);
|
||||
void setNewLightDirection(const irr::core::vector3df& cameraPosition, const irr::core::vector3df& cameraTarget);
|
||||
|
||||
public:
|
||||
View(Engine* engine);
|
||||
~View();
|
||||
void setZUp(bool zUp);
|
||||
float cameraDistance();
|
||||
void setCameraDistance(float cameraDistance);
|
||||
bool zUp();
|
||||
bool m_Shift;
|
||||
|
|
|
@ -24,6 +24,9 @@ if [ -d "$dump_dest" ]; then
|
|||
fi
|
||||
mkdir "$dump_dest" || customDie "Cannot mkdir $dump_dest"
|
||||
chmod +x ./etc/pushtmp.sh
|
||||
if [ ! -f "`command -v clang-format`" ]; then
|
||||
customDie "clang-format command is not in path. You must install clang."
|
||||
fi
|
||||
echo "* Using -style=WebKit to avoid .clang-format version issues..."
|
||||
#echo "* rewriting .clang-format to avoid clang-format version issues..."
|
||||
#rewriting avoids the following error:
|
||||
|
|
Loading…
Reference in New Issue