mirror of
https://github.com/TorqueGameEngines/Torque3D.git
synced 2026-03-03 20:40:35 +00:00
Add all new AFX files
This commit is contained in:
parent
f2b86b7df3
commit
ace877b409
218 changed files with 54970 additions and 0 deletions
280
Engine/source/afx/util/afxAnimCurve.cpp
Normal file
280
Engine/source/afx/util/afxAnimCurve.cpp
Normal file
|
|
@ -0,0 +1,280 @@
|
|||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
||||
// Arcane-FX for MIT Licensed Open Source version of Torque 3D from GarageGames
|
||||
// Copyright (C) 2015 Faust Logic, Inc.
|
||||
//
|
||||
// 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 "afx/arcaneFX.h"
|
||||
#include "afx/util/afxAnimCurve.h"
|
||||
|
||||
afxAnimCurve::afxAnimCurve() : usable( false ), final_value( 0.0f ), start_value( 0.0f )
|
||||
{
|
||||
evaluator = new afxHermiteEval();
|
||||
}
|
||||
|
||||
afxAnimCurve::~afxAnimCurve()
|
||||
{
|
||||
delete evaluator;
|
||||
}
|
||||
|
||||
void afxAnimCurve::addKey( Point2F &v )
|
||||
{
|
||||
Key k;
|
||||
k.time = v.x;
|
||||
k.value = v.y;
|
||||
|
||||
keys.push_back( k );
|
||||
|
||||
usable = false;
|
||||
}
|
||||
|
||||
void afxAnimCurve::addKey( F32 time, F32 value )
|
||||
{
|
||||
Key k;
|
||||
k.time = time;
|
||||
k.value = value;
|
||||
|
||||
keys.push_back( k );
|
||||
|
||||
usable = false;
|
||||
}
|
||||
|
||||
void afxAnimCurve::setKeyTime( int index, F32 t )
|
||||
{
|
||||
if( ( index < 0 ) || ( index >= keys.size() ) )
|
||||
return;
|
||||
|
||||
Key &k = keys[index];
|
||||
k.time = t;
|
||||
|
||||
usable = false;
|
||||
}
|
||||
|
||||
void afxAnimCurve::setKeyValue( int index, F32 v )
|
||||
{
|
||||
if( ( index < 0 ) || ( index >= keys.size() ) )
|
||||
return;
|
||||
|
||||
Key &k = keys[index];
|
||||
k.value = v;
|
||||
|
||||
if( index == 0 )
|
||||
start_value = v;
|
||||
else if( index == keys.size()-1 )
|
||||
final_value = v;
|
||||
}
|
||||
|
||||
//bool afxAnimCurve::compare_Key( const afxAnimCurve::Key &a, const afxAnimCurve::Key &b )
|
||||
//{
|
||||
// return a.time < b.time;
|
||||
//}
|
||||
|
||||
S32 QSORT_CALLBACK afxAnimCurve::compare_Key( const void* a, const void* b )
|
||||
{
|
||||
const Key *key_a = (Key *)a;
|
||||
const Key *key_b = (Key *)b;
|
||||
|
||||
//Con::printf( "*** %f %f", key_a->time, key_b->time );
|
||||
|
||||
//return key_a->time < key_b->time;
|
||||
|
||||
|
||||
if (key_a->time > key_b->time)
|
||||
return 1;
|
||||
else if (key_a->time < key_b->time)
|
||||
return -1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
void afxAnimCurve::sort( )
|
||||
{
|
||||
if( keys.size() == 0 )
|
||||
return;
|
||||
|
||||
//std::sort( keys.begin(), keys.end(), afxAnimCurve::compare_Key );
|
||||
dQsort( keys.address(), keys.size(), sizeof(Key), afxAnimCurve::compare_Key );
|
||||
|
||||
start_value = keys[0].value;
|
||||
final_value = keys[keys.size()-1].value;
|
||||
|
||||
start_time = keys[0].time;
|
||||
final_time = keys[keys.size()-1].time;
|
||||
|
||||
usable = true;
|
||||
}
|
||||
|
||||
int afxAnimCurve::numKeys()
|
||||
{
|
||||
return keys.size();
|
||||
}
|
||||
|
||||
F32 afxAnimCurve::getKeyTime( int index )
|
||||
{
|
||||
if( ( index < 0 ) || ( index >= keys.size() ) )
|
||||
return 0.0f;
|
||||
|
||||
Key &k = keys[index];
|
||||
return k.time;
|
||||
}
|
||||
|
||||
F32 afxAnimCurve::getKeyValue( int index )
|
||||
{
|
||||
if( ( index < 0 ) || ( index >= keys.size() ) )
|
||||
return 0.0f;
|
||||
|
||||
Key &k = keys[index];
|
||||
return k.value;
|
||||
}
|
||||
|
||||
Point2F afxAnimCurve::getSegment( F32 time )
|
||||
{
|
||||
Point2F segment( 0, 0 );
|
||||
|
||||
if( keys.size() == 0 )
|
||||
return segment;
|
||||
|
||||
int start_index = 0;
|
||||
for( ; start_index < keys.size()-1; start_index++ )
|
||||
{
|
||||
if( time < keys[start_index+1].time )
|
||||
break;
|
||||
}
|
||||
int end_index = start_index+1;
|
||||
|
||||
segment.x = (F32)start_index;
|
||||
segment.y = (F32)end_index;
|
||||
|
||||
return segment;
|
||||
}
|
||||
|
||||
F32 afxAnimCurve::evaluate( F32 time )
|
||||
{
|
||||
if( !usable )
|
||||
return 0.0f;
|
||||
|
||||
if( time <= start_time )
|
||||
return start_value;
|
||||
|
||||
if( time >= final_time )
|
||||
return final_value;
|
||||
|
||||
if( keys.size() == 1 )
|
||||
return start_value;
|
||||
|
||||
int start_index = 0;
|
||||
for( ; start_index < keys.size()-1; start_index++ )
|
||||
{
|
||||
if( time < keys[start_index+1].time )
|
||||
break;
|
||||
}
|
||||
int end_index = start_index+1;
|
||||
|
||||
Key k0 = keys[start_index];
|
||||
Key k1 = keys[end_index];
|
||||
|
||||
Point2F v0( (F32) k0.time, k0.value );
|
||||
Point2F v1( (F32) k1.time, k1.value );
|
||||
|
||||
// Compute tangents
|
||||
Point2F tan0 = computeTangentK0( v0, v1, start_index );
|
||||
Point2F tan1 = computeTangentK1( v0, v1, end_index );
|
||||
|
||||
F32 time_perc = (F32)( time - k0.time ) / (F32)( k1.time - k0.time );
|
||||
|
||||
Point2F vnew = evaluator->evaluateCurve( v0,
|
||||
v1,
|
||||
tan0,
|
||||
tan1,
|
||||
time_perc );
|
||||
|
||||
return vnew.y;
|
||||
}
|
||||
|
||||
Point2F afxAnimCurve::computeTangentK0( Point2F &k0, Point2F &k1, int start_index )
|
||||
{
|
||||
Point2F tan0;
|
||||
|
||||
Point2F k_prev;
|
||||
Point2F k_next;
|
||||
|
||||
// tangent for k0
|
||||
if( start_index == 0 )
|
||||
{
|
||||
k_prev = k0; // Setting previous point to k0, creating a hidden point in
|
||||
// the same spot
|
||||
k_next = k1;
|
||||
}
|
||||
else
|
||||
{
|
||||
Key &k = keys[start_index-1];
|
||||
k_prev.set( k.time, k.value );
|
||||
k_next = k1;
|
||||
}
|
||||
tan0 = k_next-k_prev; //k_next.subtract( k_prev );
|
||||
tan0 *= .5f;
|
||||
|
||||
return tan0;
|
||||
}
|
||||
|
||||
Point2F afxAnimCurve::computeTangentK1( Point2F &k0, Point2F &k1, int end_index )
|
||||
{
|
||||
Point2F tan1;
|
||||
|
||||
Point2F k_prev;
|
||||
Point2F k_next;
|
||||
|
||||
// tangent for k1
|
||||
if( end_index == keys.size()-1 )
|
||||
{
|
||||
k_prev = k0;
|
||||
k_next = k1; // Setting next point to k1, creating a hidden point in
|
||||
// the same spot
|
||||
}
|
||||
else
|
||||
{
|
||||
k_prev = k0;
|
||||
Key &k = keys[end_index+1];
|
||||
k_next.set( k.time, k.value );
|
||||
}
|
||||
tan1 = k_next-k_prev; //k_next.subtract( k_prev );
|
||||
tan1 *= .5f;
|
||||
|
||||
return tan1;
|
||||
}
|
||||
|
||||
void afxAnimCurve::print()
|
||||
{
|
||||
Con::printf( "afxAnimCurve -------------------------" );
|
||||
for( int i = 0; i < keys.size(); i++ )
|
||||
{
|
||||
Key &k = keys[i];
|
||||
Con::printf( "%f: %f", k.time, k.value );
|
||||
}
|
||||
Con::printf( "-----------------------------------" );
|
||||
}
|
||||
|
||||
void afxAnimCurve::printKey( int index )
|
||||
{
|
||||
Key &k = keys[index];
|
||||
Con::printf( "%f: %f", k.time, k.value );
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue