123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332 |
- //~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
- // 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/afxCurveEval.h"
- #include "afx/util/afxCurve3D.h"
- afxCurve3D::afxCurve3D() : usable( false ), default_vector( 0, 0, 0 ), flip(false)
- {
- evaluator = new afxHermiteEval();
- }
- afxCurve3D::~afxCurve3D()
- {
- delete evaluator;
- }
- void afxCurve3D::addPoint( F32 param, Point3F &v )
- {
- if( param < 0.0f || param > 1.0f )
- return;
- CurvePoint p;
- p.parameter = param;
- p.point.set( v );
-
- points.push_back( p );
- usable = false;
- }
- void afxCurve3D::setPoint( int index, Point3F &v )
- {
- if( ( index < 0 ) || ( index >= points.size() ) )
- return;
- CurvePoint &p = points[index];
- p.point = v;
- if( index == 0 )
- start_value = v;
- else if( index == points.size()-1 )
- final_value = v;
- }
- //bool afxCurve3D::compare_CurvePoint( const afxCurve3D::CurvePoint &a, const afxCurve3D::CurvePoint &b )
- //{
- // return a.parameter < b.parameter;
- //}
- S32 QSORT_CALLBACK afxCurve3D::compare_CurvePoint( const void* a, const void* b )
- {
- //CurvePoint *cp_a = *((CurvePoint **)a);
- //CurvePoint *cp_b = *((CurvePoint **)b);
-
- const CurvePoint *cp_a = (CurvePoint *)a;
- const CurvePoint *cp_b = (CurvePoint *)b;
- //Con::printf( "*** %f %f", cp_a->parameter, cp_b->parameter );
- //return cp_a->parameter < cp_b->parameter;
- //return 1;
- if (cp_a->parameter > cp_b->parameter)
- return 1;
- else if (cp_a->parameter < cp_b->parameter)
- return -1;
- else
- return 0;
- }
- void afxCurve3D::sort( )
- {
- if( points.size() == 0 )
- return;
- if( points.size() == 1 )
- {
- start_value = points[0].point;
- final_value = start_value;
- usable = true;
- return;
- }
- //Con::printf( "*** pre-sort" );
- //std::sort( points.begin(), points.end(), afxCurve3D::compare_CurvePoint );
- dQsort( points.address(), points.size(), sizeof(CurvePoint), afxCurve3D::compare_CurvePoint );
- //Con::printf( "*** post-sort" );
- start_value = points[0].point;
- final_value = points[points.size()-1].point;
- usable = true;
- start_tangent = evaluateTangent( 0.0f );
- final_tangent = evaluateTangent( 1.0f );
- }
- int afxCurve3D::numPoints()
- {
- return points.size();
- }
- F32 afxCurve3D::getParameter( int index )
- {
- if( ( index < 0 ) || ( index >= points.size() ) )
- return 0.0f;
- return points[index].parameter;
- }
- Point3F afxCurve3D::getPoint( int index )
- {
- if( ( index < 0 ) || ( index >= points.size() ) )
- return default_vector;
- return points[index].point;
- }
- Point3F afxCurve3D::evaluate( F32 param )
- {
- if( !usable )
- return default_vector;
- if( param <= 0.0f )
- return start_value;
-
- if( param >= 1.0f )
- return final_value;
- if( points.size() == 1 )
- return start_value;
- int start_index = 0;
- for( ; start_index < points.size()-1; start_index++ )
- {
- if( param < points[start_index+1].parameter )
- break;
- }
- int end_index = start_index+1;
- CurvePoint p0 = points[start_index];
- CurvePoint p1 = points[end_index];
- // Compute tangents
- //Point3F tan0 = computeTangentP0( p0.point, p1.point, start_index );
- //Point3F tan1 = computeTangentP1( p0.point, p1.point, end_index );
-
- F32 local_param = ( param - p0.parameter ) / ( p1.parameter - p0.parameter );
- //Point3F vnew = evaluator->evaluateCurve( p0.point,
- // p1.point,
- // tan0,
- // tan1,
- // local_param );
- Point3F vnew = evaluator->evaluateCurve( p0.point, p1.point,
- p0.tangent, p1.tangent,
- local_param );
- return vnew;
- }
- Point3F afxCurve3D::evaluateTangent( F32 param )
- {
- if( !usable )
- return default_vector;
- if( param < 0.0f )
- return start_tangent;
-
- if( param > 1.0f )
- return final_tangent;
- if( points.size() == 1 )
- return start_tangent;
- int start_index = 0;
- for( ; start_index < points.size()-1; start_index++ )
- {
- if( param < points[start_index+1].parameter )
- break;
- }
- int end_index = start_index+1;
- if( param == 1.0f )
- {
- end_index = points.size()-1;
- start_index = end_index - 1;
- }
- CurvePoint p0 = points[start_index];
- CurvePoint p1 = points[end_index];
-
- // Compute tangents
- //Point3F tan0 = computeTangentP0( p0.point, p1.point, start_index );
- //Point3F tan1 = computeTangentP1( p0.point, p1.point, end_index );
- F32 local_param = ( param - p0.parameter ) / ( p1.parameter - p0.parameter );
- //Point3F vnew = evaluator->evaluateCurveTangent( p0.point,
- // p1.point,
- // tan0,
- // tan1,
- // local_param );
- Point3F vnew = evaluator->evaluateCurveTangent( p0.point, p1.point,
- p0.tangent, p1.tangent,
- local_param );
- return vnew;
- }
- Point3F afxCurve3D::computeTangentP0( Point3F &p0, Point3F &p1, int start_index )
- {
- Point3F tan0;
-
- Point3F p_prev;
- Point3F p_next;
- // tangent for p0
- if( start_index == 0 )
- {
- p_prev = p0; // Setting previous point to p0, creating a hidden point in
- // the same spot
- p_next = p1;
- }
- else
- {
- CurvePoint &p = points[start_index-1];
- p_prev = p.point;
- p_next = p1;
- }
- tan0 = p_next-p_prev; //p_next.subtract( p_prev );
- tan0 *= .5f; //= tan0.scale( .5f );
- return tan0;
- }
- Point3F afxCurve3D::computeTangentP1( Point3F &p0, Point3F &p1, int end_index )
- {
- Point3F tan1;
-
- Point3F p_prev;
- Point3F p_next;
- // tangent for p1
- if( end_index == points.size()-1 )
- {
- p_prev = p0;
- p_next = p1; // Setting next point to p1, creating a hidden point in
- // the same spot
- }
- else
- {
- p_prev = p0;
- CurvePoint &p = points[end_index+1];
- p_next = p.point;
- }
- tan1 = p_next-p_prev; //p_next.subtract( p_prev );
- tan1 *= .5f; //= tan1.scale( .5f );
- //Con::printf("UPDATE");
- return tan1;
- }
- void afxCurve3D::computeTangents()
- {
- CurvePoint *p_prev;
- CurvePoint *p_next;
- for( int i = 0; i < points.size(); i++ )
- {
- CurvePoint *p = &points[i];
-
- if( i == 0 )
- {
- p_prev = p; // Setting previous point to p0, creating a hidden point in
- // the same spot
- p_next = &points[i+1];
- }
- else if( i == points.size()-1 )
- {
- p_prev = &points[i-1];
- p_next = p; // Setting next point to p1, creating a hidden point in
- // the same spot
- }
- else
- {
- p_prev = &points[i-1];
- p_next = &points[i+1];
- }
- p->tangent = p_next->point - p_prev->point;
- //(p->tangent).normalize();
- p->tangent *= .5f;
- //Con::printf( "%d: %f %f %f", i, p->tangent.x, p->tangent.y, p->tangent.z );
- }
- }
- void afxCurve3D::print()
- {
- Con::printf( "afxCurve3D -------------------------" );
- for( int i = 0; i < points.size(); i++ )
- {
- CurvePoint &p = points[i];
- Con::printf( "%f: %f %f %f", p.parameter, p.point.x, p.point.y, p.point.z );
- }
- Con::printf( "---------------------------------" );
- }
|