improve ui, target, improve pan

master
poikilos 2019-04-19 15:29:30 -04:00
parent fe7e4c6a5c
commit 036c0feb01
12 changed files with 535 additions and 195 deletions

View File

@ -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

View File

@ -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()

View File

@ -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();
};

View File

@ -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);

View File

@ -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

View File

@ -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;
}

View File

@ -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();

View File

@ -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);

View File

@ -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
View File

@ -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
View File

@ -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;

View File

@ -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: