diff --git a/mesh.cpp b/mesh.cpp index 256d8c0..1237781 100755 --- a/mesh.cpp +++ b/mesh.cpp @@ -89,10 +89,10 @@ namespace vb01{ camPos=cam->getPosition(); } - Vector3 rotAxis=orient.getAxis(); + Vector3 rotAxis=orient.norm().getAxis(); if(rotAxis==Vector3::VEC_ZERO)rotAxis=Vector3::VEC_I; mat4 model=translate(mat4(1.),vec3(pos.x,pos.y,pos.z)); - model=rotate(model,orient.getAngle(),vec3(rotAxis.x,rotAxis.y,rotAxis.z)); + model=rotate(model,orient.norm().getAngle(),vec3(rotAxis.x,rotAxis.y,rotAxis.z)); model=glm::scale(model,vec3(scale.x,scale.y,scale.z)); mat4 view=lookAt(vec3(camPos.x,camPos.y,camPos.z),vec3(camPos.x+dir.x,camPos.y+dir.y,camPos.z+dir.z),vec3(up.x,up.y,up.z)); mat4 proj=perspective(radians(fov),width/height,nearPlane,farPlane); diff --git a/node.cpp b/node.cpp index 5245d02..a78c299 100755 --- a/node.cpp +++ b/node.cpp @@ -112,6 +112,13 @@ namespace vb01{ text->setNode(this); } + void Node::lookAt(Vector3 newDir){ + Vector3 dir=getLocalAxis(0).norm(); + float angle=dir.getAngleBetween(newDir.norm()); + Vector3 rotAxis=dir.cross(newDir.norm()); + orientation=Quaternion(angle,rotAxis)*orientation; + } + void Node::getDescendants(Node *node, vector &descendants){ for(int i=0;igetNumChildren();i++){ if(node->getChild(i)->getNumChildren()>0) diff --git a/node.h b/node.h index 289e281..2bf06ab 100755 --- a/node.h +++ b/node.h @@ -28,6 +28,7 @@ namespace vb01{ void dettachChild(Node*); void addLight(Light*); void addText(Text*); + void lookAt(Vector3); Transform getWorldTransform(); Vector3 getLocalAxis(int); inline Text* getText(int i){return texts[i];} diff --git a/quaternion.h b/quaternion.h index 4e441f6..359a447 100755 --- a/quaternion.h +++ b/quaternion.h @@ -17,7 +17,8 @@ namespace vb01{ *this=this->fromAngle(angle,axis); } Quaternion(){} - inline vb01::Quaternion operator* (vb01::Quaternion q){ + inline Quaternion operator- (){return Quaternion(w,-x,-y,-z);} + inline Quaternion operator* (Quaternion q){ float a1=this->w,a2=q.w, b1=this->x,b2=q.x, c1=this->y,c2=q.y, @@ -28,27 +29,27 @@ namespace vb01{ float z=a1*d2+b1*c2-c1*b2+d1*a2; return Quaternion(w,x,y,z); } - inline vb01::Vector3 operator* (vb01::Vector3 v){ + inline Vector3 operator* (Vector3 v){ Quaternion vQuat=(*this)*Quaternion(0,v.x,v.y,v.z)*recip(); return Vector3(vQuat.x,vQuat.y,vQuat.z); } - inline vb01::Quaternion fromAngle(float angle, Vector3 axis){ + inline Quaternion fromAngle(float angle, Vector3 axis){ return Quaternion(cos(angle/2),axis.x*sin(angle/2),axis.y*sin(angle/2),axis.z*sin(angle/2)); } inline float getAngle(){return 2*acos(w);} - inline vb01::Vector3 getAxis(){return Vector3(asin(x),asin(y),asin(z))*2;} - inline vb01::Quaternion operator+(Quaternion q){return Quaternion(w+q.w,x+q.x,y+q.y,z+q.z);} - inline vb01::Quaternion operator-(Quaternion q){return Quaternion(w-q.w,x-q.x,y-q.y,z-q.z);} - template inline vb01::Quaternion operator*(T s){return Quaternion(w*s,x*s,y*s,z*s);} - template inline vb01::Quaternion operator/(T s){return Quaternion(w/s,x/s,y/s,z/s);} - inline vb01::Quaternion conj(){ - return (*this+vb01::Quaternion(0,1,0,0) - *(*this)*vb01::Quaternion(0,1,0,0)+vb01::Quaternion(0,0,1,0) - *(*this)*vb01::Quaternion(0,0,1,0)+vb01::Quaternion(0,0,0,1) - *(*this)*vb01::Quaternion(0,0,0,1))*-.5; + inline Vector3 getAxis(){return getAngle()==0?Vector3(1,0,0):Vector3(x,y,z).norm();} + inline Quaternion operator+(Quaternion q){return Quaternion(w+q.w,x+q.x,y+q.y,z+q.z);} + inline Quaternion operator-(Quaternion q){return Quaternion(w-q.w,x-q.x,y-q.y,z-q.z);} + template inline Quaternion operator*(T s){return Quaternion(w*s,x*s,y*s,z*s);} + template inline Quaternion operator/(T s){return Quaternion(w/s,x/s,y/s,z/s);} + inline Quaternion conj(){ + return (*this+Quaternion(0,1,0,0) + *(*this)*Quaternion(0,1,0,0)+Quaternion(0,0,1,0) + *(*this)*Quaternion(0,0,1,0)+Quaternion(0,0,0,1) + *(*this)*Quaternion(0,0,0,1))*-.5; } - inline vb01::Quaternion norm(){return *this/getLength();} - inline vb01::Quaternion recip(){return conj()/getLengthSq();} + inline Quaternion norm(){return *this/getLength();} + inline Quaternion recip(){return conj()/getLengthSq();} inline float getLengthSq(){return w*w+x*x+y*y+z*z;} inline float getLength(){return std::sqrt(getLengthSq());} diff --git a/vector.h b/vector.h index ff07253..9735de0 100755 --- a/vector.h +++ b/vector.h @@ -30,7 +30,8 @@ namespace vb01{ this->y=y; this->z=z; } - bool operator==(const Vector3 &v){return x==v.x&&y==v.y&&z==v.z;} + bool operator!=(const Vector3 &v){return x!=v.x||y!=v.y||z!=v.z;} + bool operator==(const Vector3 &v){return x==v.x&&y==v.y&&z==v.z;} Vector3 operator-(){return Vector3(-x,-y,-z);} Vector3 operator-(const Vector3 &v){return Vector3(x-v.x,y-v.y,z-v.z);} Vector3 operator+(const Vector3 &v){return Vector3(x+v.x,y+v.y,z+v.z);} @@ -43,8 +44,8 @@ namespace vb01{ float dot(Vector3 v){return x*v.x+y*v.y+z*v.z;} float getAngleBetween(Vector3 v){return std::acos(dot(v));} float getDistanceFrom(Vector3 v){return (v-*this).getLengthSq();} - Vector3 norm(){return *this/getLength();} - Vector3 cross(Vector3 v){return Vector3(y*v.z-v.y*z,x*v.z-v.x*z,x*v.y-v.x*y);} + Vector3 norm(){return (*this!=Vector3::VEC_ZERO?*this/getLength():Vector3::VEC_ZERO);} + Vector3 cross(Vector3 v){return Vector3(y * v.z - v.y * z, z * v.x - x * v.z, x * v.y - v.x * y);} float x,y,z; static const Vector3 VEC_IJK, VEC_I,VEC_J,VEC_K,VEC_ZERO;