mirror of https://github.com/Poikilos/b3view
finish camera revolve feature, add pan, ms3d mime type
parent
6013175ad9
commit
924c4864e1
|
@ -1,5 +1,14 @@
|
|||
# Changelog
|
||||
|
||||
## [git] - 2019-03-09
|
||||
(poikilos)
|
||||
### Added
|
||||
* completed rotation controls (Blender-like)
|
||||
* pan up and down (Blender-like, but only up and down)
|
||||
* Z or Y to switch ("up" axis)
|
||||
* change up axis to Z when 3ds is loaded
|
||||
* model-ms3d.xml mime type file
|
||||
|
||||
## [git] - 2019-03-09
|
||||
(poikilos)
|
||||
### Added
|
||||
|
|
66
Engine.cpp
66
Engine.cpp
|
@ -132,10 +132,20 @@ s32 Engine::getNumberOfVertices()
|
|||
|
||||
Engine::Engine()
|
||||
{
|
||||
// For monitoring single press: see
|
||||
// <http://irrlicht.sourceforge.net/forum/viewtopic.php?p=210744>
|
||||
for (u32 i=0; i<KEY_KEY_CODES_COUNT; ++i)
|
||||
KeyIsDown[i] = false;
|
||||
for (u32 i=0; i<KEY_KEY_CODES_COUNT; ++i)
|
||||
keyState[i] = 0;
|
||||
LMouseState = 0;
|
||||
RMouseState = 0;
|
||||
|
||||
this->worldFPS = 60;
|
||||
this->prevFPS = 30;
|
||||
this->textureExtensions.push_back(L"png");
|
||||
this->textureExtensions.push_back(L"jpg");
|
||||
this->textureExtensions.push_back(L"bmp");
|
||||
#if WIN32
|
||||
m_Device = createDevice( EDT_DIRECT3D9, dimension2d<u32>( 1024, 768 ), 32, false, false, false, nullptr );
|
||||
#else
|
||||
|
@ -184,7 +194,7 @@ Engine::Engine()
|
|||
m_WindowSize->Width = m_Driver->getScreenSize().Width;
|
||||
m_WindowSize->Height = m_Driver->getScreenSize().Height;
|
||||
|
||||
// (do not calculate m_Yaw and m_Pitch, here, but in View constructor)
|
||||
// (do not calculate m_Yaw and m_Pitch here--see View constructor)
|
||||
|
||||
this->playAnimation();
|
||||
}
|
||||
|
@ -209,6 +219,53 @@ void Engine::loadMesh( const wstring &fileName )
|
|||
if (mesh != nullptr) {
|
||||
m_LoadedMesh = m_Scene->addAnimatedMeshSceneNode( mesh );
|
||||
Utility::dumpMeshInfoToConsole( m_LoadedMesh );
|
||||
if (Utility::toLower(Utility::extensionOf(fileName)) == L"3ds") {
|
||||
m_View->setZUp(true);
|
||||
}
|
||||
else {
|
||||
m_View->setZUp(false);
|
||||
}
|
||||
if (m_LoadedMesh != nullptr) {
|
||||
ICameraSceneNode *camera = this->m_Scene->getActiveCamera();
|
||||
aabbox3d<f32> box = m_LoadedMesh->getTransformedBoundingBox();
|
||||
vector3d<float> extents = box.getExtent();
|
||||
if (m_View->zUp()) {
|
||||
float oldDist = m_CamPos.getDistanceFrom(m_CamTarget);
|
||||
float newDist = oldDist;
|
||||
if (oldDist != 0) {
|
||||
vector3d<float> center = box.getCenter();
|
||||
vector3df edges[8];
|
||||
box.getEdges(edges);
|
||||
/*
|
||||
/3--------/7
|
||||
/ | / |
|
||||
/ | / |
|
||||
1---------5 |
|
||||
| 2- - -| -6
|
||||
| / | /
|
||||
|/ | /
|
||||
0---------4/
|
||||
*/
|
||||
newDist = 0;
|
||||
for (int i=0; i<8; i++) {
|
||||
float tryDist = center.getDistanceFrom(edges[i]);
|
||||
if (tryDist>newDist) newDist = tryDist;
|
||||
}
|
||||
newDist *= 2; // so camera doesn't touch model
|
||||
if (!Utility::equalsApprox<float>(newDist, oldDist)) {
|
||||
float scale = newDist / oldDist; // already checked 0
|
||||
vector3df oldCamPos = camera->getPosition();
|
||||
m_CamPos = oldCamPos;
|
||||
m_CamPos.X = m_CamPos.X * scale;
|
||||
m_CamPos.Y = m_CamPos.Y * scale;
|
||||
m_CamPos.Z = m_CamPos.Z * scale;
|
||||
oldCamPos = m_CamPos;
|
||||
m_View->setCameraDistance(m_CamPos.getDistanceFrom(m_CamTarget));
|
||||
camera->setPosition(m_CamPos);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -310,6 +367,13 @@ void Engine::setAnimationFPS(u32 animationFPS)
|
|||
}
|
||||
}
|
||||
|
||||
void Engine::setZUp(bool zUp)
|
||||
{
|
||||
if (this->m_View != nullptr) {
|
||||
this->m_View->setZUp(zUp);
|
||||
}
|
||||
}
|
||||
|
||||
u32 Engine::animationFPS()
|
||||
{
|
||||
u32 ret = 0;
|
||||
|
|
4
Engine.h
4
Engine.h
|
@ -63,6 +63,9 @@ private:
|
|||
irr::core::vector3df m_CamPos;
|
||||
irr::core::vector3df m_CamTarget;
|
||||
std::wstring m_FontPath = L"ClearSansRegular.ttf"; // core::stringc has implicit conversion to io::path
|
||||
bool KeyIsDown[irr::KEY_KEY_CODES_COUNT];
|
||||
irr::s32 keyState[irr::KEY_KEY_CODES_COUNT];
|
||||
irr::s32 LMouseState,RMouseState;
|
||||
|
||||
public:
|
||||
std::wstring m_PreviousPath;
|
||||
|
@ -83,6 +86,7 @@ public:
|
|||
void pauseAnimation();
|
||||
void toggleAnimation();
|
||||
void setAnimationFPS(irr::u32 animationFPS);
|
||||
void setZUp(bool zUp);
|
||||
irr::u32 animationFPS();
|
||||
};
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
# b3view
|
||||
Press 't' for Minetest ../textures with this (poikilos') forked model
|
||||
viewer for B3D, X, or OBJ files (or any supported by Irrlicht).
|
||||
viewer for B3D, X, OBJ, MS3D, 3DS (or any supported by Irrlicht).
|
||||
|
||||
![screenshot with gull from poikilos mobs_sky fork](https://github.com/poikilos/b3view/raw/master/screenshot.jpg)
|
||||
|
||||
|
@ -126,12 +126,17 @@ only applies to Visual Studio users.)
|
|||
the model file's own directory will be used.
|
||||
* `F5`: Reload last model file
|
||||
* `r`: Reload last texture file
|
||||
* 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;
|
||||
automatically changed to Z when 3ds file is loaded)
|
||||
|
||||
## Known Issues
|
||||
* Warn on missing texture.
|
||||
* Test and complete install.bat on Windows.
|
||||
* Look for fonts on OS X (see "Set Font for UI Elements" in
|
||||
UserInterface.cpp).
|
||||
* (View.cpp) Set pitch correctly for shift & middle mouse button drag.
|
||||
|
||||
## Authors
|
||||
* ClearSansRegular.ttf (**Apache 2.0 License**) by Intel
|
||||
|
|
|
@ -161,14 +161,6 @@ void UserInterface::handleMenuItemPressed( IGUIContextMenu *menu )
|
|||
UserInterface::UserInterface( Engine *engine )
|
||||
{
|
||||
this->playbackStartStopButton = nullptr;
|
||||
// For monitoring single press: see
|
||||
// <http://irrlicht.sourceforge.net/forum/viewtopic.php?p=210744>
|
||||
for (u32 i=0; i<KEY_KEY_CODES_COUNT; ++i)
|
||||
KeyIsDown[i] = false;
|
||||
for (u32 i=0; i<KEY_KEY_CODES_COUNT; ++i)
|
||||
keyState[i] = 0;
|
||||
LMouseState = 0;
|
||||
RMouseState = 0;
|
||||
|
||||
m_Engine = engine;
|
||||
m_Gui = engine->getGUIEnvironment();
|
||||
|
@ -266,8 +258,11 @@ bool UserInterface::OnEvent( const SEvent &event )
|
|||
{
|
||||
// Events arriving here should be destined for us
|
||||
if (event.EventType == EET_KEY_INPUT_EVENT) {
|
||||
if (event.KeyInput.PressedDown && !KeyIsDown[event.KeyInput.Key]) {
|
||||
if (event.KeyInput.Key == irr::KEY_KEY_T) {
|
||||
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) {
|
||||
|
@ -276,8 +271,11 @@ bool UserInterface::OnEvent( const SEvent &event )
|
|||
else if (event.KeyInput.Key == irr::KEY_KEY_R) {
|
||||
m_Engine->reloadTexture();
|
||||
}
|
||||
else if (event.KeyInput.Key == irr::KEY_F5) {
|
||||
m_Engine->reloadMesh();
|
||||
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.Char == L'+' || event.KeyInput.Char == L'=') {
|
||||
m_Engine->setAnimationFPS(m_Engine->animationFPS() + 5);
|
||||
|
@ -292,7 +290,7 @@ bool UserInterface::OnEvent( const SEvent &event )
|
|||
}
|
||||
// std::wcerr << "Char: " << event.KeyInput.Char << endl;
|
||||
}
|
||||
KeyIsDown[event.KeyInput.Key] = event.KeyInput.PressedDown;
|
||||
m_Engine->KeyIsDown[event.KeyInput.Key] = event.KeyInput.PressedDown;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -302,30 +300,26 @@ bool UserInterface::OnEvent( const SEvent &event )
|
|||
switch ( event.MouseInput.Event)
|
||||
{
|
||||
case EMIE_LMOUSE_LEFT_UP:
|
||||
if ( LMouseState == 2)
|
||||
{
|
||||
LMouseState = 3;
|
||||
if ( m_Engine->LMouseState == 2) {
|
||||
m_Engine->LMouseState = 3;
|
||||
}
|
||||
break;
|
||||
|
||||
case EMIE_LMOUSE_PRESSED_DOWN:
|
||||
if ( LMouseState == 0)
|
||||
{
|
||||
LMouseState = 1;
|
||||
if ( m_Engine->LMouseState == 0) {
|
||||
m_Engine->LMouseState = 1;
|
||||
}
|
||||
break;
|
||||
|
||||
case EMIE_RMOUSE_LEFT_UP:
|
||||
if ( RMouseState == 2)
|
||||
{
|
||||
RMouseState = 3;
|
||||
if ( m_Engine->RMouseState == 2) {
|
||||
m_Engine->RMouseState = 3;
|
||||
}
|
||||
break;
|
||||
|
||||
case EMIE_RMOUSE_PRESSED_DOWN:
|
||||
if ( RMouseState == 0)
|
||||
{
|
||||
RMouseState = 1;
|
||||
if ( m_Engine->RMouseState == 0) {
|
||||
m_Engine->RMouseState = 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -45,10 +45,6 @@ private:
|
|||
bool m_WireframeDisplay;
|
||||
bool m_Lighting;
|
||||
|
||||
bool KeyIsDown[irr::KEY_KEY_CODES_COUNT];
|
||||
irr::s32 keyState[irr::KEY_KEY_CODES_COUNT];
|
||||
irr::s32 LMouseState,RMouseState;
|
||||
|
||||
public:
|
||||
irr::gui::IGUIButton *playbackStartStopButton;
|
||||
irr::gui::IGUIButton *playbackIncreaseButton;
|
||||
|
|
|
@ -187,3 +187,9 @@ bool Utility::isFile(const std::wstring& name) {
|
|||
}
|
||||
|
||||
|
||||
//don't do late instantiation (see header file)
|
||||
//template<typename T>
|
||||
//bool Utility::equalsApprox(T f1, T f2)
|
||||
//{
|
||||
// return abs(f2-f1) < .00000001; // TODO: kEpsilon? (see also <https://en.wikipedia.org/wiki/Machine_epsilon#How_to_determine_machine_epsilon>)
|
||||
//}
|
||||
|
|
6
Utils.h
6
Utils.h
|
@ -20,6 +20,12 @@ public:
|
|||
static std::string toString(const std::wstring &name);
|
||||
static std::string toLower(const std::string &s);
|
||||
static std::wstring toLower(const std::wstring &s);
|
||||
// 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>
|
||||
static bool equalsApprox(T f1, T f2) {
|
||||
return abs(f2-f1) < .00000001; // TODO: kEpsilon? (see also <https://en.wikipedia.org/wiki/Machine_epsilon#How_to_determine_machine_epsilon>)
|
||||
}
|
||||
};
|
||||
|
||||
#endif // UTILS_H
|
||||
|
|
168
View.cpp
168
View.cpp
|
@ -1,4 +1,5 @@
|
|||
#include "View.h"
|
||||
#include <iostream>
|
||||
#include "Engine.h"
|
||||
|
||||
using namespace irr;
|
||||
|
@ -6,29 +7,73 @@ using namespace irr::core;
|
|||
using namespace irr::scene;
|
||||
|
||||
void View::setNewCameraPosition()
|
||||
{
|
||||
setNewCameraPosition(m_zUp);
|
||||
}
|
||||
|
||||
void View::setNewCameraPosition(bool zUp)
|
||||
{
|
||||
vector3d<f32> newCameraPosition;
|
||||
ICameraSceneNode *camera = m_Engine->m_Scene->getActiveCamera();
|
||||
|
||||
if (zUp) {
|
||||
camera->setUpVector(vector3df(0, 0, 1));
|
||||
}
|
||||
else {
|
||||
camera->setUpVector(vector3df(0, 1, 0));
|
||||
}
|
||||
|
||||
vector3df oldCamPos = camera->getPosition();
|
||||
// vector3df oldCamRot = camera->getRotation();
|
||||
// NOTE: rotationToDirection converts a rotation to a vec3 direction.
|
||||
// vector3df oldCamRot = m_Engine->tmpPosVec3f.?(m_Engine->tmpTargetVec3f);
|
||||
newCameraPosition.X = 0;
|
||||
newCameraPosition.Y = m_CameraDistance * sin( m_Pitch );
|
||||
newCameraPosition.Z = m_CameraDistance * cos( m_Pitch );
|
||||
|
||||
matrix4 yawMatrix;
|
||||
yawMatrix.setRotationRadians( vector3df( 0, m_Yaw, 0 ));
|
||||
yawMatrix.transformVect( newCameraPosition );
|
||||
if (m_zUp != zUp) {
|
||||
float z;
|
||||
z = oldCamPos.Y;
|
||||
oldCamPos.Y = oldCamPos.Z;
|
||||
oldCamPos.Z = z;
|
||||
z = m_Engine->m_CamPos.Y;
|
||||
m_Engine->m_CamPos.Y = m_Engine->m_CamPos.Z;
|
||||
m_Engine->m_CamPos.Z = z;
|
||||
z = m_Engine->m_CamTarget.Y;
|
||||
m_Engine->m_CamTarget.Y = m_Engine->m_CamTarget.Z;
|
||||
m_Engine->m_CamTarget.Z = z;
|
||||
camera->setPosition(m_Engine->m_CamPos);
|
||||
camera->setTarget(m_Engine->m_CamTarget);
|
||||
}
|
||||
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));
|
||||
}
|
||||
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 = oldCamPos.Y;
|
||||
yawMatrix.transformVect(newCameraPosition);
|
||||
|
||||
if (zUp) {
|
||||
//camera->setUpVector(vector3df(0, 0, 1));
|
||||
//newCameraPosition.Z = oldCamPos.Z;
|
||||
}
|
||||
else {
|
||||
//camera->setUpVector(vector3df(0, 1, 0));
|
||||
//newCameraPosition.Y = oldCamPos.Y;
|
||||
}
|
||||
camera->setPosition( newCameraPosition );
|
||||
// vector3df newRotation();
|
||||
// camera->setRotation();
|
||||
// camera->setTarget(m_Engine->tmpTargetVec3f);
|
||||
camera->setTarget(m_Engine->m_CamTarget);
|
||||
|
||||
// Set Light direction
|
||||
setNewLightDirection( newCameraPosition );
|
||||
m_zUp = zUp;
|
||||
// std::wcerr << L" setCameraPosition pitch: " << m_Pitch << endl;
|
||||
}
|
||||
|
||||
void View::setNewLightDirection( const vector3df &cameraPosition )
|
||||
|
@ -43,6 +88,7 @@ void View::setNewLightDirection( const vector3df &cameraPosition )
|
|||
|
||||
View::View( Engine *engine )
|
||||
{
|
||||
m_zUp = false;
|
||||
m_Engine = engine;
|
||||
m_LastMousePosition = new vector2d<int>();
|
||||
m_RotMouse = false;
|
||||
|
@ -50,16 +96,17 @@ View::View( Engine *engine )
|
|||
m_Pitch = PI;
|
||||
|
||||
// Set Camera Distance
|
||||
m_CameraDistance = 10;
|
||||
|
||||
// vectors for angle are opposite, since camera revolves around center
|
||||
// m_CameraDistance = 10;
|
||||
// m_CameraDistance = engine->m_CamTarget.getDistanceFrom(engine->m_CamPos);
|
||||
// Calculate offsetVec3 manually, since the object is needed later
|
||||
// (Vectors for angle are opposite, since camera revolves around center):
|
||||
vector3df offsetVec3(
|
||||
engine->m_CamPos.X-engine->m_CamTarget.X,
|
||||
engine->m_CamPos.Y-engine->m_CamTarget.Y,
|
||||
engine->m_CamPos.Z-engine->m_CamTarget.Z
|
||||
);
|
||||
// m_CameraDistance = sqrtf()
|
||||
m_CameraDistance = offsetVec3.getLength();
|
||||
|
||||
// NOTE: rotationToDirection converts a rotation to a vec3 direction
|
||||
// vector3df rotationVec3 = engine->tmpPosVec3f.?(engine->tmpTargetVec3f);
|
||||
// vector3df rotationVec3 = engine->tmpTargetVec3f.?(engine->tmpPosVec3f);
|
||||
|
@ -82,6 +129,23 @@ View::~View()
|
|||
delete m_LastMousePosition;
|
||||
}
|
||||
|
||||
void View::setZUp(bool zUp)
|
||||
{
|
||||
if (zUp != m_zUp) {
|
||||
setNewCameraPosition(zUp);
|
||||
}
|
||||
}
|
||||
|
||||
void View::setCameraDistance(float cameraDistance)
|
||||
{
|
||||
m_CameraDistance = cameraDistance;
|
||||
}
|
||||
|
||||
bool View::zUp()
|
||||
{
|
||||
return m_zUp;
|
||||
}
|
||||
|
||||
// IEventReceiver
|
||||
bool View::OnEvent( const SEvent &event )
|
||||
{
|
||||
|
@ -126,15 +190,83 @@ bool View::OnEvent( const SEvent &event )
|
|||
|
||||
m_LastMousePosition->X = mouseEvent->X;
|
||||
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;
|
||||
ICameraSceneNode *camera = m_Engine->m_Scene->getActiveCamera();
|
||||
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;
|
||||
if (m_zUp) {
|
||||
camRot.Z = m_Yaw;
|
||||
forwards = vector3df(0, 1, 0);
|
||||
dirVec3.rotateYZBy(camRot.X);
|
||||
dirVec3.rotateXYBy(camRot.Z);
|
||||
}
|
||||
else {
|
||||
camRot.Z = m_Pitch;
|
||||
dirVec3.rotateYZBy(camRot.X);
|
||||
dirVec3.rotateXYBy(camRot.Y);
|
||||
}
|
||||
// vector3df dirVec3 = rotationVec3.rotationToDirection(forwards);
|
||||
// // move up and down, not in and out:
|
||||
// float z = dirVec3.Z;
|
||||
// dirVec3.Z = dirVec3.Y;
|
||||
// dirVec3.Z = z;
|
||||
dirVec3.X *= yDelta;
|
||||
dirVec3.Y *= yDelta;
|
||||
dirVec3.Z *= yDelta;
|
||||
m_Engine->m_CamPos.X += dirVec3.X;
|
||||
m_Engine->m_CamPos.Y += dirVec3.Y;
|
||||
m_Engine->m_CamPos.Z += dirVec3.Z;
|
||||
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;
|
||||
}
|
||||
else {
|
||||
//m_Engine->m_CamPos.Y += yDelta;
|
||||
//m_Engine->m_CamTarget.Y += yDelta;
|
||||
}
|
||||
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();
|
||||
|
||||
f32 pitchDelta = dy / 120.0f;
|
||||
if(( m_Pitch - pitchDelta > ( PI - ( PI / 2 ))) && ( m_Pitch - pitchDelta < PI + ( PI/2 )))
|
||||
m_Pitch -= dy / 120.0f;
|
||||
m_Yaw = atan2(offsetVec3.X, offsetVec3.Z);
|
||||
m_Pitch = asin(-offsetVec3.Y);
|
||||
setNewCameraPosition();
|
||||
}
|
||||
else {
|
||||
// Revolve camera around object.
|
||||
// increments of 120 pixels * PI are equal to 180 deg (PI radians):
|
||||
f32 pitchDelta = dy / 120.0f;
|
||||
// (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;
|
||||
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;
|
||||
// std::wcerr << "pitch = " << m_Pitch << endl;
|
||||
|
||||
m_Yaw += dx / 120.0f;
|
||||
m_Yaw += dx / 120.0f;
|
||||
|
||||
// Set Camera to new rotation
|
||||
setNewCameraPosition();
|
||||
// Set Camera to new rotation
|
||||
setNewCameraPosition();
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
|
|
6
View.h
6
View.h
|
@ -12,13 +12,19 @@ private:
|
|||
irr::f32 m_Yaw, m_Pitch, 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 );
|
||||
|
||||
public:
|
||||
View( Engine *engine );
|
||||
~View();
|
||||
void setZUp(bool zUp);
|
||||
void setCameraDistance(float cameraDistance);
|
||||
bool zUp();
|
||||
bool m_Shift;
|
||||
|
||||
// IEventReceiver
|
||||
virtual bool OnEvent( const irr::SEvent &event );
|
||||
|
|
118
build/install.sh
118
build/install.sh
|
@ -113,50 +113,84 @@ if [ ! -d "$MIMETYPES_DB_PATH/packages" ]; then
|
|||
mkdir "$MIMETYPES_DB_PATH/packages"
|
||||
fi
|
||||
update_mime_enable=false
|
||||
if [ -f "$mime_path" ]; then
|
||||
# echo "Copying as '$MIMETYPES_DB_PATH/packages/$mime_name'..."
|
||||
try_dest="$MIMETYPES_DB_PATH/packages/$mime_name"
|
||||
if diff -q $mime_path $try_dest; then
|
||||
echo "(You already have an identical $try_dest)"
|
||||
else
|
||||
cp -f "$mime_path" "$MIMETYPES_DB_PATH/packages/"
|
||||
if [ -f "$try_dest" ]; then
|
||||
echo "Successfully copied '$try_dest'"
|
||||
update_mime_enable=true
|
||||
fi
|
||||
fi
|
||||
mime_name=model-x.xml
|
||||
mime_path="$mimes_path/$mime_name"
|
||||
try_dest="$MIMETYPES_DB_PATH/packages/$mime_name"
|
||||
if diff -q $mime_path $try_dest; then
|
||||
echo "(You already have an identical $try_dest)"
|
||||
else
|
||||
cp -f "$mime_path" "$MIMETYPES_DB_PATH/packages/"
|
||||
if [ -f "$try_dest" ]; then
|
||||
echo "Successfully copied '$try_dest'"
|
||||
update_mime_enable=true
|
||||
fi
|
||||
fi
|
||||
|
||||
# Since OBJ Mime type is broken on linux (detected as TGIF), trying
|
||||
# to add an overlapping mime type breaks it worse (KDE detects the
|
||||
# file as "plain text file" if the xml file below is installed)
|
||||
mime_name=model-obj.xml
|
||||
mime_path="$mimes_path/$mime_name"
|
||||
# cp -f "$mime_path" "$MIMETYPES_DB_PATH/packages/"
|
||||
# if [ -f "$MIMETYPES_DB_PATH/packages/$mime_name" ]; then
|
||||
# echo "Successfully copied '$MIMETYPES_DB_PATH/packages/$mime_name'"
|
||||
# rm -f "$MIMETYPES_DB_PATH/packages/$mime_name"
|
||||
# fi
|
||||
|
||||
if [ "@$update_mime_enable" = "@true" ]; then
|
||||
echo "Updating mime type database '$MIMETYPES_DB_PATH'..."
|
||||
update-mime-database "$MIMETYPES_DB_PATH" # must contain packages
|
||||
fi
|
||||
echo "Done."
|
||||
if [ ! -f "$mime_path" ]; then
|
||||
echo "ERROR: Stopped installing mime types since missing $mime_path"
|
||||
exit 1
|
||||
fi
|
||||
try_dest="$MIMETYPES_DB_PATH/packages/$mime_name"
|
||||
if diff -q $mime_path $try_dest; then
|
||||
echo "* (You already have an identical $try_dest)"
|
||||
else
|
||||
echo "ERROR: $mime_path must be in working directory in order to install it using this script."
|
||||
cp -f "$mime_path" "$MIMETYPES_DB_PATH/packages/"
|
||||
if [ -f "$try_dest" ]; then
|
||||
echo "* Successfully copied '$try_dest'"
|
||||
update_mime_enable=true
|
||||
fi
|
||||
fi
|
||||
mime_name=model-x.xml
|
||||
mime_path="$mimes_path/$mime_name"
|
||||
if [ ! -f "$mime_path" ]; then
|
||||
echo "ERROR: Stopped installing mime types since missing $mime_path"
|
||||
exit 1
|
||||
fi
|
||||
try_dest="$MIMETYPES_DB_PATH/packages/$mime_name"
|
||||
if diff -q $mime_path $try_dest; then
|
||||
echo "* (You already have an identical $try_dest)"
|
||||
else
|
||||
cp -f "$mime_path" "$MIMETYPES_DB_PATH/packages/"
|
||||
if [ -f "$try_dest" ]; then
|
||||
echo "* Successfully copied '$try_dest'"
|
||||
update_mime_enable=true
|
||||
fi
|
||||
fi
|
||||
|
||||
# Since OBJ Mime type is broken on linux (detected as TGIF obj/sym
|
||||
# hyperlinked vector graphics format unrelated to Wavefront OBJ
|
||||
# format but sharing the same file extension), trying
|
||||
# to add an overlapping mime type breaks it worse (KDE detects the
|
||||
# file as "plain text file" if the xml file below is installed)
|
||||
mime_name=model-obj.xml
|
||||
mime_path="$mimes_path/$mime_name"
|
||||
#if [ ! -f "$mime_path" ]; then
|
||||
#echo "ERROR: Stopped installing mime types since missing $mime_path"
|
||||
#exit 1
|
||||
#fi
|
||||
try_dest="$MIMETYPES_DB_PATH/packages/$mime_name"
|
||||
#if diff -q $mime_path $try_dest; then
|
||||
#echo "* (You already have an identical $try_dest)"
|
||||
#else
|
||||
#cp -f "$mime_path" "$MIMETYPES_DB_PATH/packages/"
|
||||
if [ -f "$MIMETYPES_DB_PATH/packages/$mime_name" ]; then
|
||||
# echo "* Successfully copied '$MIMETYPES_DB_PATH/packages/$mime_name'"
|
||||
echo "* Removing '$MIMETYPES_DB_PATH/packages/$mime_name' (overlaps with system usually)"
|
||||
rm -f "$MIMETYPES_DB_PATH/packages/$mime_name"
|
||||
update_mime_enable=true
|
||||
fi
|
||||
#fi
|
||||
|
||||
mime_name=model-ms3d.xml
|
||||
mime_path="$mimes_path/$mime_name"
|
||||
if [ ! -f "$mime_path" ]; then
|
||||
echo "ERROR: Stopped installing mime types since missing $mime_path"
|
||||
exit 1
|
||||
fi
|
||||
try_dest="$MIMETYPES_DB_PATH/packages/$mime_name"
|
||||
if diff -q $mime_path $try_dest; then
|
||||
echo "(You already have an identical $try_dest)"
|
||||
else
|
||||
cp -f "$mime_path" "$MIMETYPES_DB_PATH/packages/"
|
||||
if [ -f "$MIMETYPES_DB_PATH/packages/$mime_name" ]; then
|
||||
echo "Successfully copied '$MIMETYPES_DB_PATH/packages/$mime_name'"
|
||||
# rm -f "$MIMETYPES_DB_PATH/packages/$mime_name"
|
||||
update_mime_enable=true
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ "@$update_mime_enable" = "@true" ]; then
|
||||
echo "Updating mime type database '$MIMETYPES_DB_PATH'..."
|
||||
update-mime-database "$MIMETYPES_DB_PATH" # must contain packages
|
||||
fi
|
||||
echo "Done."
|
||||
|
||||
echo
|
||||
echo
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<mime-info xmlns="http://www.freedesktop.org/standards/shared-mime-info">
|
||||
<mime-type type="model/ms3d">
|
||||
<comment>MilkShape 3D Model File</comment>
|
||||
<icon name="model-ms3d"/>
|
||||
<glob-deleteall/>
|
||||
<glob pattern="*.ms3d"/>
|
||||
</mime-type>
|
||||
</mime-info>
|
|
@ -1,11 +1,11 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<mime-info xmlns="http://www.freedesktop.org/standards/shared-mime-info">
|
||||
<mime-type type="model/obj">
|
||||
<comment>OBJ file</comment>
|
||||
<comment>Wavefront OBJ Model File</comment>
|
||||
<icon name="model-obj"/>
|
||||
<glob-deleteall/>
|
||||
<remove fileExtension=".obj" />
|
||||
<mimeMap fileExtension=".obj" mimeType="text/plain" />
|
||||
<mimeMap fileExtension=".obj" mimeType="model/obj" />
|
||||
<glob pattern="*.obj"/>
|
||||
</mime-type>
|
||||
</mime-info>
|
||||
|
|
Loading…
Reference in New Issue