SurfaceCtrl: Fixed bug about focus and zoom, improved the way trackball is handled

git-svn-id: svn://ultimatepp.org/upp/trunk@14774 f0d560ea-af0d-0410-9eb7-867de7ffcac7
This commit is contained in:
xemuth 2020-08-07 21:51:25 +00:00
parent 711b0273e6
commit 8cd930a717
5 changed files with 80 additions and 45 deletions

View file

@ -5,7 +5,7 @@
namespace Upp{
class SketchupCamera : public UOGL_Camera {
public:
glm::vec3 focus = glm::vec3(10.0f,10.0f,0.0f); //point the camera will focus
glm::vec3 focus = glm::vec3(-5.0f,5.0f, 2.0f); //point the camera will focus
SketchupCamera(){}
virtual SketchupCamera* Clone(){
@ -14,14 +14,16 @@ class SketchupCamera : public UOGL_Camera {
SketchupCamera& Init(){
SetPosition(glm::vec3(2.0f,3.0f,5.0f));
LookAt(focus);
if( focus != glm::vec3(0,0,0))
transform.SetPosition(focus - (2.0f * (focus)));
else
transform.SetPosition(0,0,5);
return *this;
}
virtual glm::mat4 GetViewMatrix(){
return glm::lookAt(transform.GetPosition(), focus , transform.GetUp());
return glm::lookAt( transform.GetPosition() + focus , focus , transform.GetUp());
}
virtual SketchupCamera& ProcessKeyboardMouvement(Camera_Movement direction){
@ -40,25 +42,28 @@ class SketchupCamera : public UOGL_Camera {
if(AbsA1 > AbsA2) a2 = 0.0f;
else a1 = 0.0f;
glm::vec3 v = transform.GetPosition() ;
glm::vec3 v = transform.GetPosition();
glm::quat upRotation = Transform::GetQuaterion(a1,transform.GetWorldUp());
glm::quat rightRotation = Transform::GetQuaterion(a2,glm::normalize(glm::cross(transform.GetUp(),v))); // Quat using the right vector
v = glm::rotate(upRotation, v);
v = glm::rotate(rightRotation, v);
transform.SetPosition(v);
transform.Rotate(glm::inverse(upRotation * rightRotation));
transform.SetPosition(v);
return *this;
}
virtual SketchupCamera& ProcessMouseLeftMouvement(float xoffset, float yoffset){
xoffset *= (MouseSensitivity * MouvementSpeed);
yoffset *= (MouseSensitivity * MouvementSpeed);
yoffset *= -1.0f;
Cout() << "yoffset : " << yoffset << EOL;
float Absx = sqrt(pow(xoffset,2));
float Absy = sqrt(pow(yoffset,2));
if(Absx > Absy) yoffset = 0.0f;else xoffset = 0.0f;
transform.Move(0,yoffset,0);
focus += glm::vec3(0.0f,yoffset,0.0f);
glm::vec3 ri = transform.GetRight() * xoffset + transform.GetUp() * yoffset;
transform.Move(ri);
focus += ri;
return *this;
}
@ -72,11 +77,13 @@ class SketchupCamera : public UOGL_Camera {
}
virtual SketchupCamera& ProcessMouseScroll(float zdelta){
glm::vec3 scaling = (0.1f * (transform.GetPosition()));
if(zdelta == - 120){
transform.SetPosition(transform.GetPosition() + (0.1f * transform.GetPosition()));
transform.SetPosition(transform.GetPosition() + scaling);
}else{
transform.SetPosition(transform.GetPosition() - (0.1f * transform.GetPosition()));
float dot = sqrt(pow(glm::dot(transform.GetPosition(),scaling),2));
if(dot > 1.0f)
transform.SetPosition(transform.GetPosition() - scaling);
}
return *this;
}

View file

@ -55,6 +55,7 @@ void SurfaceCtrl::GLPaint(){
if(!loaded){
OnBegin();
Axis = objProvider.Begin(GL_LINES).AddAxis(0,0,0,200000).End();
CameraFocus = objProvider.Begin(GL_TRIANGLE_FAN).AddCube(0.0f,0.0f,0.0f,1,Red()).End();
loaded = true;
}
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
@ -62,6 +63,10 @@ void SurfaceCtrl::GLPaint(){
WhenPaint(); //The function wich loop arround all object and draw using proper VAO and shaders
if(ShowAxis)
Axis.Draw(camera.GetProjectionMatrix(Upp::Sizef{sizeW,sizeH}), camera.GetViewMatrix(),camera.GetTransform().GetPosition(), DrawMeshNoLight,DrawMeshNoLight,DrawMeshNoLight,DrawMeshNoLight);
if(ShowCameraFocus){
CameraFocus.GetTransform().SetPosition(camera.focus);
CameraFocus.Draw(camera.GetProjectionMatrix(Upp::Sizef{sizeW,sizeH}), camera.GetViewMatrix(),camera.GetTransform().GetPosition(), DrawMeshNoLight,DrawMeshNoLight,DrawMeshNoLight,DrawMeshNoLight);
}
}
void SurfaceCtrl::CreateObject(Surface& surf, Color color)noexcept{
Object3D& obj = allObjects.Create(surf,color);
@ -94,9 +99,7 @@ void SurfaceCtrl::DrawAllObjects(){
void SurfaceCtrl::InitCamera()noexcept{
camera.Init();
camera.SetMouseSensitivity(0.80f);
camera.SetMouvementSpeed(2.0f);
camera.GetTransform().SetPosition(0,0,5);
camera.GetTransform().SetRotation(0.0f,0.0f,0.0f);
camera.SetMouvementSpeed(15.0f);
}
void SurfaceCtrl::GLResize(int w, int h){
sizeW = w;
@ -140,16 +143,16 @@ bool SurfaceCtrl::Key(dword key,int count){
if(allObjects.GetCount() > 0) allObjects[0].ShowMeshNormal(!allObjects[0].GetShowMeshNormal());
}
if(key == K_LEFT){
camera.ProcessMouseWheelMouvement(2,0);
camera.ProcessMouseWheelMouvement(2 * camera.GetMouvementSpeed(),0);
}
if(key == K_RIGHT){
camera.ProcessMouseWheelMouvement(-2,0);
camera.ProcessMouseWheelMouvement(-2 * camera.GetMouvementSpeed(),0);
}
if(key == K_UP){
camera.ProcessMouseWheelMouvement(0,2);
camera.ProcessMouseWheelMouvement(0,2 * camera.GetMouvementSpeed());
}
if(key == K_DOWN){
camera.ProcessMouseWheelMouvement(0,-2);
camera.ProcessMouseWheelMouvement(0,-2 * camera.GetMouvementSpeed());
}
if(key == K_ADD){
camera.SetFOV(camera.GetFOV() + 5);
@ -166,6 +169,9 @@ bool SurfaceCtrl::Key(dword key,int count){
if(key == K_A){
ShowAxis = !ShowAxis;
}
if(key == K_F){
ShowCameraFocus = !ShowCameraFocus;
}
/*
Material change
*/

View file

@ -32,6 +32,7 @@ class SurfaceCtrl : public GLCtrl_glad{
Upp::Vector<Object3D> allObjects;
Object3D Axis;
Object3D CameraFocus;
/*
UOGL_Camera* camera;
@ -47,6 +48,7 @@ class SurfaceCtrl : public GLCtrl_glad{
OpenGLProgram DrawMeshNormal;
bool ShowAxis = true;
bool ShowCameraFocus = true;
float sizeW = 800.0f;
float sizeH = 600.0f;

View file

@ -68,27 +68,25 @@ class TrackBallCamera : public UOGL_Camera {
return transform4(vector, glm::toMat4(rotation));
}
virtual TrackBallCamera& ProcessMouveMouvement(float xoffset, float yoffset){
if(MouseLeftPressed){
xoffset *= MouseSensitivity;
yoffset *= MouseSensitivity;
//Another approach
// Determine rotation angles from the change in mouse position
float a1 = (xoffset/2.0f) *-1.0f;
float a2 = yoffset/2.0f;
// Rotate the target->eye vectoraround the up vector
glm::vec3 v = transform.GetPosition() + focus;
v = RotateAround(a1,v,up);
// Determine the right vector and rotate the target->eye and up around it
glm::vec3 r = glm::cross(up,v);
r = glm::normalize(r);
v = RotateAround(a2,v,r);
up = RotateAround(a2,up,r);
up = glm::normalize(up);
transform.SetPosition(v);
}
virtual TrackBallCamera& ProcessMouseWheelMouvement(float xoffset,float yoffset){
xoffset *= MouseSensitivity;
yoffset *= MouseSensitivity;
//Another approach
// Determine rotation angles from the change in mouse position
float a1 = (xoffset/2.0f) *-1.0f;
float a2 = yoffset/2.0f;
// Rotate the target->eye vectoraround the up vector
glm::vec3 v = transform.GetPosition() + focus;
v = RotateAround(a1,v,up);
// Determine the right vector and rotate the target->eye and up around it
glm::vec3 r = glm::cross(up,v);
r = glm::normalize(r);
v = RotateAround(a2,v,r);
up = RotateAround(a2,up,r);
up = glm::normalize(up);
transform.SetPosition(v);
//transform.SetRotation(glm::quatLookAt(focus - transform.GetPosition(), glm::vec3(0.0f,1.0f,0.0f)) );
@ -126,7 +124,26 @@ class TrackBallCamera : public UOGL_Camera {
return *this;
}
virtual TrackBallCamera& ProcessMouseLeftMouvement(float xoffset, float yoffset){
yoffset *= -1.0f;
float Absx = sqrt(pow(xoffset,2));
float Absy = sqrt(pow(yoffset,2));
if(Absx > Absy) yoffset = 0.0f;else xoffset = 0.0f;
glm::vec3 ri = transform.GetRight() * xoffset + transform.GetUp() * yoffset;
transform.Move(ri);
focus += ri;
return *this;
}
virtual TrackBallCamera& ProcessMouveMouvement(float xoffset, float yoffset){
if(MouseMiddlePressed) return ProcessMouseWheelMouvement(xoffset,yoffset);
if(MouseLeftPressed) return ProcessMouseLeftMouvement(xoffset,yoffset);
}
virtual bool ProcessKeyBoard(unsigned long Key,int count){
/*
if( Key == Upp::K_Z){

View file

@ -69,12 +69,15 @@ class Transform{
Transform& Rotate(float Yaw, float Pitch, float Roll)noexcept{Rotation *= glm::quat(glm::vec3(Pitch, Yaw , Roll)); RecalculateFURW(); return *this;}
Transform& Rotate(float angleDegree, const glm::vec3& axis){float radHalfAngle =(float) glm::radians(angleDegree) / 2.0f; float sinVal = glm::sin(radHalfAngle); float cosVal = glm::cos(radHalfAngle); float xVal = axis.x * sinVal; float yVal = axis.y * sinVal; float zVal = axis.z * sinVal; Rotation *= glm::quat(cosVal,xVal, yVal, zVal); RecalculateFURW(); return *this;}
Transform& LookAt(const glm::vec3& LookAt)noexcept{
Transform& LookAt(const glm::vec3& LookAt, glm::vec3 customUp = glm::vec3(0.0f,0.0f,0.0f))noexcept{
glm::vec3 direction = LookAt - Position;
float directionLength = glm::length(direction);
if(directionLength > 0.0001){
direction /= directionLength;
SetRotation(glm::quatLookAt(glm::normalize(direction), Up));
if(customUp != glm::vec3(0.0f,0.0f,0.0f))
SetRotation(glm::quatLookAt(glm::normalize(direction), customUp));
else
SetRotation(glm::quatLookAt(glm::normalize(direction), Up));
}
return *this;
}