diff --git a/src/apps/glteapot/GLObject.cpp b/src/apps/glteapot/GLObject.cpp index 58ca79bf4c..f46c464acb 100644 --- a/src/apps/glteapot/GLObject.cpp +++ b/src/apps/glteapot/GLObject.cpp @@ -1,3 +1,16 @@ +/* + * Copyright 2008 Haiku Inc. All rights reserved. + * Distributed under the terms of the MIT License. + * + * Authors: + * Alexandre Deckner + * + */ + +/* + * Original Be Sample source modified to use a quaternion for the object's orientation + */ + /* Copyright 1999, Be Incorporated. All Rights Reserved. This file may be used under the terms of the Be Sample Code License. @@ -61,16 +74,13 @@ extern long setEvent(sem_id event); GLObject::GLObject(ObjectView* ov) : - rotX(0), - rotY(0), - spinX(2), - spinY(2), x(0), y(0), z(-2.0), + fRotation(0.0f, 0.0f, 0.0f, 1.0f), + spinX(2), + spinY(2), solidity(0), - lastRotX(0), - lastRotY(0), color(4), changed(false), fObjView(ov) @@ -131,29 +141,53 @@ GLObject::MenuInvoked(BPoint point) setEvent(fObjView->drawEvent); } +int +GLObject::Solidity() const +{ + return solidity; +} + bool GLObject::SpinIt() { - rotX += spinX; - rotY += spinY; bool c = changed; - c = c || ((rotX != lastRotX) || (rotY != lastRotY)); - lastRotX = rotX; - lastRotY = rotY; + c = c || ((spinX != 0.0f) || (spinY != 0.0f)); + + if (c) + RotateWorldSpace(spinY, spinX); return c; } +void +GLObject::Spin(float rx, float ry) +{ + spinX = rx; + spinY = ry; +} + + +void +GLObject::RotateWorldSpace(float rx, float ry) +{ + fRotation = Quaternion(Vector3(0.0f, 1.0f, 0.0f), 0.01f * rx) * fRotation; + fRotation = Quaternion(Vector3(1.0f, 0.0f, 0.0f), 0.01f * ry) * fRotation; + changed = true; +} + + void GLObject::Draw(bool forID, float IDcolor[]) { glPushMatrix(); glTranslatef(x, y, z); - glRotatef(rotY, 0.0,1.0,0.0); - glRotatef(rotX, 1.0,0.0,0.0); - + + float mat[4][4]; + fRotation.toOpenGLMatrix(mat); + glMultMatrixf((GLfloat*)mat); + if (forID) { glColor3fv(IDcolor); } diff --git a/src/apps/glteapot/GLObject.h b/src/apps/glteapot/GLObject.h index 020e5a763e..aad6508548 100644 --- a/src/apps/glteapot/GLObject.h +++ b/src/apps/glteapot/GLObject.h @@ -1,12 +1,27 @@ +/* + * Copyright 2008 Haiku Inc. All rights reserved. + * Distributed under the terms of the MIT License. + * + * Authors: + * Alexandre Deckner + * + */ + +/* + * Original Be Sample source modified to use a quaternion for the object's orientation + */ + /* Copyright 1999, Be Incorporated. All Rights Reserved. This file may be used under the terms of the Be Sample Code License. */ + #ifndef GL_OBJECT_H #define GL_OBJECT_H #include "ObjectView.h" #include "util.h" +#include "Quaternion.h" struct point { float x,y,z; @@ -29,16 +44,21 @@ class GLObject { GLObject(ObjectView* ov); virtual ~GLObject(); virtual void Draw(bool forID, float IDcolor[]); + virtual bool SpinIt(); + void Spin(float rx, float ry); + void RotateWorldSpace(float rx, float ry); virtual void MenuInvoked(BPoint point); virtual void DoDrawing(bool forID) {}; + int Solidity() const; - float rotX, rotY, spinX, spinY; float x, y, z; - int solidity; - + Quaternion fRotation; + protected: - float lastRotX, lastRotY; + + float spinX, spinY; + int solidity; int color; bool changed; diff --git a/src/apps/glteapot/ObjectView.cpp b/src/apps/glteapot/ObjectView.cpp index 4368c7b896..52f91859e7 100644 --- a/src/apps/glteapot/ObjectView.cpp +++ b/src/apps/glteapot/ObjectView.cpp @@ -1,3 +1,16 @@ +/* + * Copyright 2008 Haiku Inc. All rights reserved. + * Distributed under the terms of the MIT License. + * + * Authors: + * Alexandre Deckner + * + */ + +/* + * Original Be Sample source modified to use a quaternion for the object's orientation + */ + /* Copyright 1999, Be Incorporated. All Rights Reserved. This file may be used under the terms of the Be Sample Code License. @@ -409,13 +422,13 @@ ObjectView::MouseDown(BPoint point) if (buttons == B_PRIMARY_MOUSE_BUTTON || buttons == B_SECONDARY_MOUSE_BUTTON) { fTrackingInfo.pickedObject = object; fTrackingInfo.buttons = buttons; - fTrackingInfo.isTracking = true; + fTrackingInfo.isTracking = true; fTrackingInfo.lastX = point.x; - fTrackingInfo.lastY = point.y; + fTrackingInfo.lastY = point.y; fTrackingInfo.lastDx = 0.0f; - fTrackingInfo.lastDy = 0.0f; - fTrackingInfo.pickedObject->spinX = 0.0f; - fTrackingInfo.pickedObject->spinY = 0.0f; + fTrackingInfo.lastDy = 0.0f; + fTrackingInfo.pickedObject->Spin(0.0f, 0.0f); + SetMouseEventMask(B_POINTER_EVENTS, B_LOCK_WINDOW_FOCUS | B_NO_POINTER_HISTORY); @@ -437,9 +450,8 @@ ObjectView::MouseUp(BPoint point) && fTrackingInfo.pickedObject != NULL && (fabs(fTrackingInfo.lastDx) > 1.0f || fabs(fTrackingInfo.lastDy) > 1.0f) ) { - - fTrackingInfo.pickedObject->spinX = 0.5f * fTrackingInfo.lastDy; - fTrackingInfo.pickedObject->spinY = 0.5f * fTrackingInfo.lastDx; + + fTrackingInfo.pickedObject->Spin(0.5f * fTrackingInfo.lastDy, 0.5f * fTrackingInfo.lastDx); setEvent(drawEvent); } @@ -468,10 +480,8 @@ ObjectView::MouseMoved(BPoint point, uint32 transit, const BMessage *msg) if (fTrackingInfo.buttons == B_PRIMARY_MOUSE_BUTTON) { - fTrackingInfo.pickedObject->spinX = 0; - fTrackingInfo.pickedObject->spinY = 0; - fTrackingInfo.pickedObject->rotY += dx; - fTrackingInfo.pickedObject->rotX += dy; + fTrackingInfo.pickedObject->Spin(0.0f, 0.0f); + fTrackingInfo.pickedObject->RotateWorldSpace(dx,dy); fTrackingInfo.lastDx = dx; fTrackingInfo.lastDy = dy; @@ -489,12 +499,12 @@ ObjectView::MouseMoved(BPoint point, uint32 transit, const BMessage *msg) yinc *= -(fTrackingInfo.pickedObject->z * 4 / zRatio); } - fTrackingInfo.pickedObject->x += xinc; + fTrackingInfo.pickedObject->x += xinc; if (modifiers() & B_SHIFT_KEY) fTrackingInfo.pickedObject->z += zinc; else fTrackingInfo.pickedObject->y += yinc; - + fForceRedraw = true; setEvent(drawEvent); } @@ -721,13 +731,13 @@ ObjectView::DrawFrame(bool noPause) fObjListLock.Lock(); for (int i = 0; i < fObjects.CountItems(); i++) { GLObject *object = reinterpret_cast(fObjects.ItemAt(i)); - if (object->solidity == 0) + if (object->Solidity() == 0) object->Draw(false, NULL); } EnforceState(); for (int i = 0; i < fObjects.CountItems(); i++) { GLObject *object = reinterpret_cast(fObjects.ItemAt(i)); - if (object->solidity != 0) + if (object->Solidity() != 0) object->Draw(false, NULL); } fObjListLock.Unlock(); diff --git a/src/apps/glteapot/ObjectView.h b/src/apps/glteapot/ObjectView.h index 1e38c62845..8f515da644 100644 --- a/src/apps/glteapot/ObjectView.h +++ b/src/apps/glteapot/ObjectView.h @@ -1,3 +1,9 @@ +/* + * Copyright 2008 Haiku Inc. All rights reserved. + * Distributed under the terms of the MIT License. + * + */ + /* Copyright 1999, Be Incorporated. All Rights Reserved. This file may be used under the terms of the Be Sample Code License. diff --git a/src/apps/glteapot/Quaternion.h b/src/apps/glteapot/Quaternion.h new file mode 100755 index 0000000000..9207f480f3 --- /dev/null +++ b/src/apps/glteapot/Quaternion.h @@ -0,0 +1,408 @@ +/* + * Copyright 2008 Haiku Inc. All rights reserved. + * Distributed under the terms of the MIT License. + * + * Authors: + * Alexandre Deckner + * + */ + +/* + * + * This is a refactored and stripped down version of bullet-2.66 src\LinearMath\btQuaternion.h + * The dependancies on base class btQuadWord have been removed for simplification. + * Added gl matrix conversion method. + * + */ + +/* +Copyright (c) 2003-2006 Gino van den Bergen / Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + + +#ifndef __QUATERNION_H__ +#define __QUATERNION_H__ + +#include "Vector3.h" + +class Quaternion { +protected: + float m_x; + float m_y; + float m_z; + float m_w; +public: + Quaternion() {} + + Quaternion(const Quaternion& q) + { + *((Quaternion*)this) = q; + } + + Quaternion(const float& x, const float& y, const float& z,const float& w) + { + m_x = x, m_y = y, m_z = z, m_w = w; + } + + Quaternion(const Vector3& axis, const float& angle) + { + setRotation(axis, angle); + } + + Quaternion(const float& yaw, const float& pitch, const float& roll) + { + setEuler(yaw, pitch, roll); + } + + inline const float& x() const { return m_x; } + + + inline const float& y() const { return m_y; } + + + inline const float& z() const { return m_z; } + + + inline const float& w() const { return m_w; } + + + void setValue(const float& x, const float& y, const float& z) + { + m_x=x; + m_y=y; + m_z=z; + m_w = 0.f; + } + + + void setValue(const float& x, const float& y, const float& z,const float& w) + { + m_x=x; + m_y=y; + m_z=z; + m_w=w; + } + + + void setRotation(const Vector3& axis, const float& angle) + { + float d = axis.length(); + assert(d != float(0.0)); + float s = sin(angle * float(0.5)) / d; + setValue(axis.x() * s, axis.y() * s, axis.z() * s, + cos(angle * float(0.5))); + } + + + void setEuler(const float& yaw, const float& pitch, const float& roll) + { + float halfYaw = float(yaw) * float(0.5); + float halfPitch = float(pitch) * float(0.5); + float halfRoll = float(roll) * float(0.5); + float cosYaw = cos(halfYaw); + float sinYaw = sin(halfYaw); + float cosPitch = cos(halfPitch); + float sinPitch = sin(halfPitch); + float cosRoll = cos(halfRoll); + float sinRoll = sin(halfRoll); + setValue(cosRoll * sinPitch * cosYaw + sinRoll * cosPitch * sinYaw, + cosRoll * cosPitch * sinYaw - sinRoll * sinPitch * cosYaw, + sinRoll * cosPitch * cosYaw - cosRoll * sinPitch * sinYaw, + cosRoll * cosPitch * cosYaw + sinRoll * sinPitch * sinYaw); + } + + + Quaternion& operator+=(const Quaternion& q) + { + m_x += q.x(); m_y += q.y(); m_z += q.z(); m_w += q.m_w; + return *this; + } + + + Quaternion& operator-=(const Quaternion& q) + { + m_x -= q.x(); m_y -= q.y(); m_z -= q.z(); m_w -= q.m_w; + return *this; + } + + + Quaternion& operator*=(const float& s) + { + m_x *= s; m_y *= s; m_z *= s; m_w *= s; + return *this; + } + + + Quaternion& operator*=(const Quaternion& q) + { + setValue(m_w * q.x() + m_x * q.m_w + m_y * q.z() - m_z * q.y(), + m_w * q.y() + m_y * q.m_w + m_z * q.x() - m_x * q.z(), + m_w * q.z() + m_z * q.m_w + m_x * q.y() - m_y * q.x(), + m_w * q.m_w - m_x * q.x() - m_y * q.y() - m_z * q.z()); + return *this; + } + + + float dot(const Quaternion& q) const + { + return m_x * q.x() + m_y * q.y() + m_z * q.z() + m_w * q.m_w; + } + + + float length2() const + { + return dot(*this); + } + + + float length() const + { + return sqrt(length2()); + } + + + Quaternion& normalize() + { + return *this /= length(); + } + + + inline Quaternion + operator*(const float& s) const + { + return Quaternion(x() * s, y() * s, z() * s, m_w * s); + } + + + Quaternion operator/(const float& s) const + { + assert(s != float(0.0)); + return *this * (float(1.0) / s); + } + + + Quaternion& operator/=(const float& s) + { + assert(s != float(0.0)); + return *this *= float(1.0) / s; + } + + + Quaternion normalized() const + { + return *this / length(); + } + + + float angle(const Quaternion& q) const + { + float s = sqrt(length2() * q.length2()); + assert(s != float(0.0)); + return acos(dot(q) / s); + } + + + float getAngle() const + { + float s = float(2.) * acos(m_w); + return s; + } + + + Quaternion inverse() const + { + return Quaternion(m_x, m_y, m_z, -m_w); + } + + + inline Quaternion + operator+(const Quaternion& q2) const + { + const Quaternion& q1 = *this; + return Quaternion(q1.x() + q2.x(), q1.y() + q2.y(), q1.z() + q2.z(), q1.m_w + q2.m_w); + } + + + inline Quaternion + operator-(const Quaternion& q2) const + { + const Quaternion& q1 = *this; + return Quaternion(q1.x() - q2.x(), q1.y() - q2.y(), q1.z() - q2.z(), q1.m_w - q2.m_w); + } + + + inline Quaternion operator-() const + { + const Quaternion& q2 = *this; + return Quaternion( - q2.x(), - q2.y(), - q2.z(), - q2.m_w); + } + + + inline Quaternion farthest( const Quaternion& qd) const + { + Quaternion diff,sum; + diff = *this - qd; + sum = *this + qd; + if( diff.dot(diff) > sum.dot(sum) ) + return qd; + return (-qd); + } + + + Quaternion slerp(const Quaternion& q, const float& t) const + { + float theta = angle(q); + if (theta != float(0.0)) + { + float d = float(1.0) / sin(theta); + float s0 = sin((float(1.0) - t) * theta); + float s1 = sin(t * theta); + return Quaternion((m_x * s0 + q.x() * s1) * d, + (m_y * s0 + q.y() * s1) * d, + (m_z * s0 + q.z() * s1) * d, + (m_w * s0 + q.m_w * s1) * d); + } + else + { + return *this; + } + } + + + void toOpenGLMatrix(float m[4][4]){ + + float wx, wy, wz, xx, yy, yz, xy, xz, zz, x2, y2, z2; + + // calculate coefficients + x2 = m_x + m_x; y2 = m_y + m_y; + z2 = m_z + m_z; + xx = m_x * x2; xy = m_x * y2; xz = m_x * z2; + yy = m_y * y2; yz = m_y * z2; zz = m_z * z2; + wx = m_w * x2; wy = m_w * y2; wz = m_w * z2; + + + m[0][0] = 1.0 - (yy + zz); m[1][0] = xy - wz; + m[2][0] = xz + wy; m[3][0] = 0.0; + + m[0][1] = xy + wz; m[1][1] = 1.0 - (xx + zz); + m[2][1] = yz - wx; m[3][1] = 0.0; + + + m[0][2] = xz - wy; m[1][2] = yz + wx; + m[2][2] = 1.0 - (xx + yy); m[3][2] = 0.0; + + + m[0][3] = 0; m[1][3] = 0; + m[2][3] = 0; m[3][3] = 1; + } +}; + + +inline Quaternion +operator-(const Quaternion& q) +{ + return Quaternion(-q.x(), -q.y(), -q.z(), -q.w()); +} + + +inline Quaternion +operator*(const Quaternion& q1, const Quaternion& q2) { + return Quaternion(q1.w() * q2.x() + q1.x() * q2.w() + q1.y() * q2.z() - q1.z() * q2.y(), + q1.w() * q2.y() + q1.y() * q2.w() + q1.z() * q2.x() - q1.x() * q2.z(), + q1.w() * q2.z() + q1.z() * q2.w() + q1.x() * q2.y() - q1.y() * q2.x(), + q1.w() * q2.w() - q1.x() * q2.x() - q1.y() * q2.y() - q1.z() * q2.z()); +} + + +inline Quaternion +operator*(const Quaternion& q, const Vector3& w) +{ + return Quaternion( q.w() * w.x() + q.y() * w.z() - q.z() * w.y(), + q.w() * w.y() + q.z() * w.x() - q.x() * w.z(), + q.w() * w.z() + q.x() * w.y() - q.y() * w.x(), + -q.x() * w.x() - q.y() * w.y() - q.z() * w.z()); +} + + +inline Quaternion +operator*(const Vector3& w, const Quaternion& q) +{ + return Quaternion( w.x() * q.w() + w.y() * q.z() - w.z() * q.y(), + w.y() * q.w() + w.z() * q.x() - w.x() * q.z(), + w.z() * q.w() + w.x() * q.y() - w.y() * q.x(), + -w.x() * q.x() - w.y() * q.y() - w.z() * q.z()); +} + + +inline float +dot(const Quaternion& q1, const Quaternion& q2) +{ + return q1.dot(q2); +} + + +inline float +length(const Quaternion& q) +{ + return q.length(); +} + + +inline float +angle(const Quaternion& q1, const Quaternion& q2) +{ + return q1.angle(q2); +} + + +inline Quaternion +inverse(const Quaternion& q) +{ + return q.inverse(); +} + + +inline Quaternion +slerp(const Quaternion& q1, const Quaternion& q2, const float& t) +{ + return q1.slerp(q2, t); +} + + +inline Quaternion +shortestArcQuat(const Vector3& v0, const Vector3& v1) // Game Programming Gems 2.10. make sure v0,v1 are normalized +{ + Vector3 c = v0.cross(v1); + float d = v0.dot(v1); + + if (d < -1.0 + FLT_EPSILON) + return Quaternion(0.0f,1.0f,0.0f,0.0f); // just pick any vector + + float s = sqrt((1.0f + d) * 2.0f); + float rs = 1.0f / s; + + return Quaternion(c.x()*rs, c.y()*rs, c.z()*rs, s * 0.5f); +} + + +inline Quaternion +shortestArcQuatNormalize2(Vector3& v0,Vector3& v1) +{ + v0.normalize(); + v1.normalize(); + return shortestArcQuat(v0,v1); +} +#endif + + + diff --git a/src/apps/glteapot/Vector3.h b/src/apps/glteapot/Vector3.h new file mode 100755 index 0000000000..c8d05cb194 --- /dev/null +++ b/src/apps/glteapot/Vector3.h @@ -0,0 +1,350 @@ +/* + * Copyright 2008 Haiku Inc. All rights reserved. + * Distributed under the terms of the MIT License. + * + * Authors: + * Alexandre Deckner + * + */ + +/* + * + * This is a refactored and stripped down version of bullet-2.66 src\LinearMath\btVector3.h + * The dependancies on base class btQuadWord have been removed for simplification. + * + */ + +/* +Copyright (c) 2003-2006 Gino van den Bergen / Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + + +#ifndef __VECTOR3_H__ +#define __VECTOR3_H__ + +///Vector3 can be used to represent 3D points and vectors. + +class Vector3 { +protected: + float m_x; + float m_y; + float m_z; + +public: + inline Vector3() {} + + + inline Vector3(const Vector3& v) + { + *((Vector3*)this) = v; + } + + + inline Vector3(const float& x, const float& y, const float& z) + { + m_x = x, m_y = y, m_z = z; + } + + + inline const float& x() const { return m_x; } + + + inline const float& y() const { return m_y; } + + + inline const float& z() const { return m_z; } + + + inline void setValue(const float& x, const float& y, const float& z) + { + m_x=x; + m_y=y; + m_z=z; + } + + inline Vector3& operator+=(const Vector3& v) + { + m_x += v.x(); m_y += v.y(); m_z += v.z(); + return *this; + } + + + inline Vector3& operator-=(const Vector3& v) + { + m_x -= v.x(); m_y -= v.y(); m_z -= v.z(); + return *this; + } + + + inline Vector3& operator*=(const float& s) + { + m_x *= s; m_y *= s; m_z *= s; + return *this; + } + + + inline Vector3& operator/=(const float& s) + { + //btFullAssert(s != float(0.0)); + return *this *= float(1.0) / s; + } + + + inline float dot(const Vector3& v) const + { + return m_x * v.x() + m_y * v.y() + m_z * v.z(); + } + + + inline float length2() const + { + return dot(*this); + } + + + inline float length() const + { + return sqrt(length2()); + } + + + inline float distance2(const Vector3& v) const; + + + inline float distance(const Vector3& v) const; + + + inline Vector3& normalize() + { + return *this /= length(); + } + + + inline Vector3 normalized() const; + + + inline Vector3 rotate( const Vector3& wAxis, const float angle ); + + + inline float angle(const Vector3& v) const + { + float s = sqrt(length2() * v.length2()); + //btFullAssert(s != float(0.0)); + return acos(dot(v) / s); + } + + + inline Vector3 absolute() const + { + return Vector3( + fabs(m_x), + fabs(m_y), + fabs(m_z)); + } + + + inline Vector3 cross(const Vector3& v) const + { + return Vector3( + m_y * v.z() - m_z * v.y(), + m_z * v.x() - m_x * v.z(), + m_x * v.y() - m_y * v.x()); + } + + + inline float triple(const Vector3& v1, const Vector3& v2) const + { + return m_x * (v1.y() * v2.z() - v1.z() * v2.y()) + + m_y * (v1.z() * v2.x() - v1.x() * v2.z()) + + m_z * (v1.x() * v2.y() - v1.y() * v2.x()); + } + + + inline int minAxis() const + { + return m_x < m_y ? (m_x < m_z ? 0 : 2) : (m_y < m_z ? 1 : 2); + } + + + inline int maxAxis() const + { + return m_x < m_y ? (m_y < m_z ? 2 : 1) : (m_x < m_z ? 2 : 0); + } + + + inline int furthestAxis() const + { + return absolute().minAxis(); + } + + + inline int closestAxis() const + { + return absolute().maxAxis(); + } + + + inline void setInterpolate3(const Vector3& v0, const Vector3& v1, float rt) + { + float s = float(1.0) - rt; + m_x = s * v0.x() + rt * v1.x(); + m_y = s * v0.y() + rt * v1.y(); + m_z = s * v0.z() + rt * v1.z(); + //don't do the unused w component + // m_co[3] = s * v0[3] + rt * v1[3]; + } + + + inline Vector3 lerp(const Vector3& v, const float& t) const + { + return Vector3(m_x + (v.x() - m_x) * t, + m_y + (v.y() - m_y) * t, + m_z + (v.z() - m_z) * t); + } + + + inline Vector3& operator*=(const Vector3& v) + { + m_x *= v.x(); m_y *= v.y(); m_z *= v.z(); + return *this; + } + +}; + +inline Vector3 +operator+(const Vector3& v1, const Vector3& v2) +{ + return Vector3(v1.x() + v2.x(), v1.y() + v2.y(), v1.z() + v2.z()); +} + +inline Vector3 +operator*(const Vector3& v1, const Vector3& v2) +{ + return Vector3(v1.x() * v2.x(), v1.y() * v2.y(), v1.z() * v2.z()); +} + +inline Vector3 +operator-(const Vector3& v1, const Vector3& v2) +{ + return Vector3(v1.x() - v2.x(), v1.y() - v2.y(), v1.z() - v2.z()); +} + +inline Vector3 +operator-(const Vector3& v) +{ + return Vector3(-v.x(), -v.y(), -v.z()); +} + +inline Vector3 +operator*(const Vector3& v, const float& s) +{ + return Vector3(v.x() * s, v.y() * s, v.z() * s); +} + +inline Vector3 +operator*(const float& s, const Vector3& v) +{ + return v * s; +} + +inline Vector3 +operator/(const Vector3& v, const float& s) +{ + //btFullAssert(s != float(0.0)); + return v * (float(1.0) / s); +} + +inline Vector3 +operator/(const Vector3& v1, const Vector3& v2) +{ + return Vector3(v1.x() / v2.x(),v1.y() / v2.y(),v1.z() / v2.z()); +} + +inline float +dot(const Vector3& v1, const Vector3& v2) +{ + return v1.dot(v2); +} + +inline float +distance2(const Vector3& v1, const Vector3& v2) +{ + return v1.distance2(v2); +} + + +inline float +distance(const Vector3& v1, const Vector3& v2) +{ + return v1.distance(v2); +} + +inline float +angle(const Vector3& v1, const Vector3& v2) +{ + return v1.angle(v2); +} + +inline Vector3 +cross(const Vector3& v1, const Vector3& v2) +{ + return v1.cross(v2); +} + +inline float +triple(const Vector3& v1, const Vector3& v2, const Vector3& v3) +{ + return v1.triple(v2, v3); +} + +inline Vector3 +lerp(const Vector3& v1, const Vector3& v2, const float& t) +{ + return v1.lerp(v2, t); +} + + +inline bool operator==(const Vector3& p1, const Vector3& p2) +{ + return p1.x() == p2.x() && p1.y() == p2.y() && p1.z() == p2.z(); +} + +inline float Vector3::distance2(const Vector3& v) const +{ + return (v - *this).length2(); +} + +inline float Vector3::distance(const Vector3& v) const +{ + return (v - *this).length(); +} + +inline Vector3 Vector3::normalized() const +{ + return *this / length(); +} + +inline Vector3 Vector3::rotate( const Vector3& wAxis, const float angle ) +{ + // wAxis must be a unit lenght vector + + Vector3 o = wAxis * wAxis.dot( *this ); + Vector3 x = *this - o; + Vector3 y; + + y = wAxis.cross( *this ); + + return ( o + x * cos( angle ) + y * sin( angle ) ); +} + +#endif //__VECTOR3_H__