mirror of
https://github.com/TorqueGameEngines/Torque3D.git
synced 2026-01-20 12:44:46 +00:00
157 lines
4 KiB
C++
157 lines
4 KiB
C++
|
|
//-----------------------------------------------------------------------------
|
||
|
|
// Copyright (c) 2012 GarageGames, LLC
|
||
|
|
//
|
||
|
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||
|
|
// of this software and associated documentation files (the "Software"), to
|
||
|
|
// deal in the Software without restriction, including without limitation the
|
||
|
|
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||
|
|
// sell copies of the Software, and to permit persons to whom the Software is
|
||
|
|
// furnished to do so, subject to the following conditions:
|
||
|
|
//
|
||
|
|
// The above copyright notice and this permission notice shall be included in
|
||
|
|
// all copies or substantial portions of the Software.
|
||
|
|
//
|
||
|
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||
|
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||
|
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||
|
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||
|
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||
|
|
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||
|
|
// IN THE SOFTWARE.
|
||
|
|
//-----------------------------------------------------------------------------
|
||
|
|
|
||
|
|
#include "ts/tsTransform.h"
|
||
|
|
#include "core/stream/stream.h"
|
||
|
|
|
||
|
|
void Quat16::identity()
|
||
|
|
{
|
||
|
|
x = y = z = 0;
|
||
|
|
w = MAX_VAL;
|
||
|
|
}
|
||
|
|
|
||
|
|
QuatF Quat16::getQuatF() const
|
||
|
|
{
|
||
|
|
return QuatF ( F32(x) / F32(MAX_VAL),
|
||
|
|
F32(y) / F32(MAX_VAL),
|
||
|
|
F32(z) / F32(MAX_VAL),
|
||
|
|
F32(w) / F32(MAX_VAL) );
|
||
|
|
}
|
||
|
|
|
||
|
|
QuatF & Quat16::getQuatF( QuatF * q ) const
|
||
|
|
{
|
||
|
|
q->x = F32( x ) / F32(MAX_VAL);
|
||
|
|
q->y = F32( y ) / F32(MAX_VAL);
|
||
|
|
q->z = F32( z ) / F32(MAX_VAL);
|
||
|
|
q->w = F32( w ) / F32(MAX_VAL);
|
||
|
|
return *q;
|
||
|
|
}
|
||
|
|
|
||
|
|
void Quat16::set( const QuatF & q )
|
||
|
|
{
|
||
|
|
x = (S16)(q.x * F32(MAX_VAL));
|
||
|
|
y = (S16)(q.y * F32(MAX_VAL));
|
||
|
|
z = (S16)(q.z * F32(MAX_VAL));
|
||
|
|
w = (S16)(q.w * F32(MAX_VAL));
|
||
|
|
}
|
||
|
|
|
||
|
|
S32 Quat16::operator==( const Quat16 & q ) const
|
||
|
|
{
|
||
|
|
return( x == q.x && y == q.y && z == q.z && w == q.w );
|
||
|
|
}
|
||
|
|
|
||
|
|
void Quat16::read(Stream * s)
|
||
|
|
{
|
||
|
|
s->read(&x);
|
||
|
|
s->read(&y);
|
||
|
|
s->read(&z);
|
||
|
|
s->read(&w);
|
||
|
|
}
|
||
|
|
|
||
|
|
void Quat16::write(Stream * s)
|
||
|
|
{
|
||
|
|
s->write(x);
|
||
|
|
s->write(y);
|
||
|
|
s->write(z);
|
||
|
|
s->write(w);
|
||
|
|
}
|
||
|
|
|
||
|
|
QuatF & TSTransform::interpolate( const QuatF & q1, const QuatF & q2, F32 interp, QuatF * q )
|
||
|
|
{
|
||
|
|
F32 Dot;
|
||
|
|
F32 Dist2;
|
||
|
|
F32 OneOverL;
|
||
|
|
F32 x1,y1,z1,w1;
|
||
|
|
F32 x2,y2,z2,w2;
|
||
|
|
|
||
|
|
//
|
||
|
|
// This is a linear interpolation with a fast renormalization.
|
||
|
|
//
|
||
|
|
x1 = q1.x;
|
||
|
|
y1 = q1.y;
|
||
|
|
z1 = q1.z;
|
||
|
|
w1 = q1.w;
|
||
|
|
x2 = q2.x;
|
||
|
|
y2 = q2.y;
|
||
|
|
z2 = q2.z;
|
||
|
|
w2 = q2.w;
|
||
|
|
|
||
|
|
// Determine if quats are further than 90 degrees
|
||
|
|
Dot = x1*x2 + y1*y2 + z1*z2 + w1*w2;
|
||
|
|
|
||
|
|
// If dot is negative flip one of the quaterions
|
||
|
|
if( Dot < 0.0f )
|
||
|
|
{
|
||
|
|
x1 = -x1;
|
||
|
|
y1 = -y1;
|
||
|
|
z1 = -z1;
|
||
|
|
w1 = -w1;
|
||
|
|
}
|
||
|
|
|
||
|
|
// Compute interpolated values
|
||
|
|
x1 = x1 + interp*(x2 - x1);
|
||
|
|
y1 = y1 + interp*(y2 - y1);
|
||
|
|
z1 = z1 + interp*(z2 - z1);
|
||
|
|
w1 = w1 + interp*(w2 - w1);
|
||
|
|
|
||
|
|
// Get squared distance of new quaternion
|
||
|
|
Dist2 = x1*x1 + y1*y1 + z1*z1 + w1*w1;
|
||
|
|
|
||
|
|
// Use home-baked polynomial to compute 1/sqrt(Dist2)
|
||
|
|
// since we know the range is 0.707 >= Dist2 <= 1.0
|
||
|
|
// we'll split in half.
|
||
|
|
|
||
|
|
if( Dist2<0.857f )
|
||
|
|
OneOverL = (((0.699368f)*Dist2) + -1.819985f)*Dist2 + 2.126369f; //0.0000792
|
||
|
|
else
|
||
|
|
OneOverL = (((0.454012f)*Dist2) + -1.403517f)*Dist2 + 1.949542f; //0.0000373
|
||
|
|
|
||
|
|
// Renormalize
|
||
|
|
q->x = x1*OneOverL;
|
||
|
|
q->y = y1*OneOverL;
|
||
|
|
q->z = z1*OneOverL;
|
||
|
|
q->w = w1*OneOverL;
|
||
|
|
|
||
|
|
return *q;
|
||
|
|
}
|
||
|
|
|
||
|
|
void TSTransform::applyScale(F32 scale, MatrixF * mat)
|
||
|
|
{
|
||
|
|
mat->scale(Point3F(scale,scale,scale));
|
||
|
|
}
|
||
|
|
|
||
|
|
void TSTransform::applyScale(const Point3F & scale, MatrixF * mat)
|
||
|
|
{
|
||
|
|
mat->scale(scale);
|
||
|
|
}
|
||
|
|
|
||
|
|
void TSTransform::applyScale(const TSScale & scale, MatrixF * mat)
|
||
|
|
{
|
||
|
|
MatrixF mat2;
|
||
|
|
TSTransform::setMatrix(scale.mRotate,&mat2);
|
||
|
|
MatrixF mat3(mat2);
|
||
|
|
mat3.inverse();
|
||
|
|
mat2.scale(scale.mScale);
|
||
|
|
mat2.mul(mat3);
|
||
|
|
mat->mul(mat2);
|
||
|
|
}
|