/*========================================================================================= File: Bezier.c Prupose: Handle a Bezier curve Author: Yann Le Tensorer Creation Date: 23 january 1997 Version: 1.0 =========================================================================================== Revisions: Version Date Author ---------------------------------------------------------------- 1.1 3 february 1997 Yann Le Tensorer 1.2 5 february 1997 Yann Le Tensorer Added the possibility of changing the sampling rate in real-time =========================================================================================*/ /*========================================================== Notes: This module implements functions to create and draw bezier curves here is an example how to use it: { tdstBezierObject BezierCurve; long color; MTH3D_tdstVector A,B,T1,T2; ACP_tdstDynaParam stDynaParam; unsigned char ucSamplingRate; color=0xffffffff; // white A.xX=0; A.xY=0; A.xZ=0; B.xX=1; B.xY=1; B.xZ=0; T1.xX=0; T1.xY=0.25; T1.xZ=0; T2.xX=-0.25; T2.xY=0; T2.xZ=0; ucSamplingRate=20; // Sampling rate fn_vDynamicObject_Create(&stDynaParam,ucSamplingRate,C_ucSinus,0,MTH_C_Pi,255); fn_vBezierObject_Create(&BezierCurve,ucSamplingRate,&A,&B,&T1,&T2,C_ucModeNoObject,&stDynaParam); fn_vBezierObject_SetColor(&BezierCurve,color); fn_vBezierObject_SetViewPortAttributes(...); // en fonction du viewport fn_vBezierObject_Draw(&BezierCurve); fn_vBezierObject_Free(&BezierCurve); } ===========================================================*/ #ifdef _AI_LIB_ #include "AIUseCPA.h" /*#include "acp_base.h"*/ /*#include "gli.h"*/ #include "geoobj.h" #include "bezier.h" #include "IAOption.h" #include "IAMacros.h" /* AI memory and error management */ #include "MemIA.h" #include "ErrIA.h" #else /*_AI_LIB_*/ #include "acp_base.h" #include "gli.h" #include "geoobj.h" #include "bezier.h" #endif /*_AI_LIB_*/ /*============================================================ Memory management macros, to be replaced with correct memory management ============================================================*/ #ifdef _AI_LIB_ #define M_malloc(pointer,cast,size) M_IAAlloc(pointer,cast,size) #define M_free(pointer) M_IAFree(pointer) #else /*_AI_LIB_*/ #define M_malloc(pointer,cast,size) (pointer=(cast)malloc(size)) #define M_free(pointer) (free(pointer)) #endif /*_AI_LIB_*/ /*========================================================== Function name: fn_vBezierObject_Create Description: Create Bezier curve (in ram only) between two points Input: p_BezierObject: pointer to a preallocated tdstBezierObject ucSamplingRate: number of segment to define the curve) stStartPoint: First vertex of the curve stEndPoint: Last vertex of the curve stStartVector: Tangent vector at the first point stEndVector: Tangent vector at the last point ucObjectMode: Creation mode (C_ucModeNoObject ou C_ucModeRealObject) C_ucModeNoObject does not create a geometric object whereas C_ucModeRealObject does. Output: none Author: Yann Le Tensorer Date: 23 january 1997 Revision: YLT - 03 february 1997 ==========================================================*/ void fn_vBezierObject_Create( tdstBezierObject *p_BezierObject, unsigned char ucSamplingRate, MTH3D_tdstVector* p_stStartPoint, MTH3D_tdstVector* p_stEndPoint, MTH3D_tdstVector* p_stStartVector, MTH3D_tdstVector* p_stEndVector, unsigned char ucObjectMode, ACP_tdstDynaParam* p_stDynaParams ) { GEO_tdstDoubledIndex xLineDoubleIndex; long xCurVertex; if (p_BezierObject==0) return; /* avoid crash */ /* copies input parameters into objects parameters */ p_BezierObject->ucObjectMode =ucObjectMode; p_BezierObject->ucSamplingRate =ucSamplingRate; p_BezierObject->stStartPoint =*p_stStartPoint; p_BezierObject->stEndPoint =*p_stEndPoint; p_BezierObject->stStartVector =*p_stStartVector; p_BezierObject->stEndVector =*p_stEndVector; p_BezierObject->p_stDynaParams =p_stDynaParams; /* if mode is MODE_NO_OBJECT, allocates ram only for points list and dynamic parameters */ if (ucObjectMode==C_ucModeNoObject) { M_malloc ( p_BezierObject->d_stListOfPoints, MTH3D_tdstVector*, (ucSamplingRate+1)*sizeof(MTH3D_tdstVector) ); } else /* else mode is MODE_REAL_OBJET, creates the geometric object*/ { /* This list of points is not used */ p_BezierObject->d_stListOfPoints=0; /* create object with 1 element (lines only), and ucSamplingRate+1 points) */ GEO_vCreateGeometricObject(&p_BezierObject->hObject,ucSamplingRate+1,1); /* create line element*/ GEO_xCreateElementLines(p_BezierObject->hObject,&p_BezierObject->hElement,ucSamplingRate); /* create lines indexes */ for (xCurVertex=0;xCurVertexhObject,p_BezierObject->hElement,xCurVertex,&xLineDoubleIndex); } } /* calculate points of bezier curve */ fn_vBezierObject_Calculate(p_BezierObject); } /*=============================================================================== Function name: fn_bBezierObject_SetSamplingRate Description: Modifies the sampling rate of a bezier object, and changes all the depending parameters (including dynamic sampling rate) Input: p_BezierObject: pointer to a preallocated tdstBezierObject ucSamplingRate: New sampling rate Output: return value is true if sampling rate could be modified, false if not. Author: Yann Le Tensorer Date: 5 february 1997 Revision: Note: The sampling rate can only be modified for objects that have been created using C_ucModeNoObject at their creation. ================================================================================*/ ACP_tdxBool fn_bBezierObject_SetSamplingRate(tdstBezierObject *p_BezierObject, unsigned char ucSamplingRate) { if (p_BezierObject==0) return FALSE; if (p_BezierObject->ucObjectMode==C_ucModeNoObject) { /* copies new sampling rate value into objects parameters */ p_BezierObject->ucSamplingRate =ucSamplingRate; if (p_BezierObject->ucSamplingRate<2) p_BezierObject->ucSamplingRate=2; /* free old list of points and allocates new one */ if (p_BezierObject->d_stListOfPoints!=0) M_free(p_BezierObject->d_stListOfPoints); M_malloc ( p_BezierObject->d_stListOfPoints, MTH3D_tdstVector*, (p_BezierObject->ucSamplingRate+1)*sizeof(MTH3D_tdstVector) ); /* calculate points of bezier curve */ fn_vBezierObject_Calculate(p_BezierObject); /* checks if dynamic parameters are attached to the object if yes, changes them to match the new sampling rate */ fn_vDynamicObject_ChangeSamplingRate(p_BezierObject->p_stDynaParams, p_BezierObject->ucSamplingRate); return TRUE; } else return FALSE; } /*========================================================== Function name: fn_vBezierObject_Free Description: Free memory allocated by the bezier objet Input: p_BezierObject: pointer to a tdstBezierObject Output: none Author: Yann Le Tensorer Date: 29 january 1997 Revision: ==========================================================*/ void fn_vBezierObject_Free(tdstBezierObject *p_BezierObject) { if (p_BezierObject!=0) { if (p_BezierObject->d_stListOfPoints!=0) M_free(p_BezierObject->d_stListOfPoints); /* if dynamic parameters are present, free memory too */ if (p_BezierObject->p_stDynaParams!=0) fn_vDynamicObject_Free(p_BezierObject->p_stDynaParams); } } /*========================================================== Function name: fn_vBezierObject_Calculate Description: Calculates the points of the bézier curve according to the parameters specified when creating the object. Input: p_BezierObject: Pointer to a pre-created bezier object Output: none Author: Yann Le Tensorer Date: 23 january 1997 Revision: ==========================================================*/ void fn_vBezierObject_Calculate(tdstBezierObject *p_BezierObject) { double xt,endxt,t,c0,c1,c2,c3,c4,c5,c6; MTH3D_tdstVector A,B,T1,T2; MTH3D_tdstVector *p_stPointList; if (p_BezierObject==0) return; /* avoid crash */ if (p_BezierObject->ucObjectMode==C_ucModeRealObject) p_stPointList=((p_BezierObject->hObject) -> d_stListOfPoints); else p_stPointList=(p_BezierObject->d_stListOfPoints); A = p_BezierObject->stStartPoint; B = p_BezierObject->stEndPoint; MTH3D_M_vAddVector(&T1,&p_BezierObject->stStartVector,&p_BezierObject->stStartPoint); MTH3D_M_vAddVector(&T2,&p_BezierObject->stEndVector,&p_BezierObject->stEndPoint); endxt= p_BezierObject->ucSamplingRate; for (xt=0;xt<=endxt;xt++) { t=xt/endxt; c0=1-t; /* 1-t */ c2=c0*c0; /* (1-t)^2 */ c1=3*t*c2; /* 3t*((1-t)^2) */ c3=t*t; /* t^2 */ c4=3*c3*c0; /* 3t^2*(1-t) */ c5=c0*c2; /* (1-t)^3 */ c6=c3*t; /* t^3 */ p_stPointList->xX=(c5*A.xX)+(c1*T1.xX)+(c4*T2.xX)+(c6*B.xX); p_stPointList->xY=(c5*A.xY)+(c1*T1.xY)+(c4*T2.xY)+(c6*B.xY); p_stPointList->xZ=(c5*A.xZ)+(c1*T1.xZ)+(c4*T2.xZ)+(c6*B.xZ); p_stPointList++; } } /*========================================================== Function name: fn_vBezierObject_SetColor Description: Set the color of a bezier object. Input: p_BezierObject: pointer to a pre-created tdstBezierObject color: 24 bit color of object. (0->7=B; 8->15=G; 16->23=R ; 24->32=Unused) Output: none Author: Yann Le Tensorer Date: 24 january 1997 Revision: ==========================================================*/ void fn_vBezierObject_SetColor(tdstBezierObject *p_BezierObject,long color) { if (p_BezierObject==0) return; /* avoid crash */ p_BezierObject->color=color; } /*========================================================== Function name: fn_vBezierObject_SetViewPortAttributes Description: Set the viewportattributes for drawing. Input: p_BezierObject: pointer to a pre-created tdstBezierObject p_ViewPortAttributes: pointer to pre-defined viewport attributes Output: none Author: Yann Le Tensorer Date: 24 january 1997 Revision: ==========================================================*/ void fn_vBezierObject_SetViewPortAttributes(tdstBezierObject *p_BezierObject,GLD_tdstViewportAttributes *p_ViewPortAttributes) { if (p_BezierObject==0) return; /* avoid crash */ p_BezierObject->p_ViewPortAttributes=p_ViewPortAttributes; } /*========================================================== Function name: fn_vBezierObject_Draw Description: Draw Bezier object on screen Input: p_BezierObject: pointer to a pre-created tdstBezierObject Output: none Author: Yann Le Tensorer Date: 24 january 1997 Revision: ==========================================================*/ void fn_vBezierObject_Draw(tdstBezierObject *p_BezierObject) { POS_tdstCompletePosition stMatrix; GEO_tdstColor ColBidon; MTH3D_tdstVector *p_stPointList; MTH3D_tdstVector *p_stPointListEnd; POS_fn_vSetIdentityMatrix(&stMatrix); if (p_BezierObject==0) return; /* avoid crash */ /*unsigned long color; */ ColBidon.xR=(float)0.5; ColBidon.xG=(float)0.5; ColBidon.xB=(float)0.5; ColBidon.xA=(float)0.5; if (p_BezierObject->ucObjectMode==C_ucModeRealObject) p_stPointList=((p_BezierObject->hObject) -> d_stListOfPoints); else p_stPointList=(p_BezierObject->d_stListOfPoints); if (p_stPointList==0) return; GLI_xGetCameraMatrix(((GLI_tdstSpecificAttributesFor3D*)((p_BezierObject->p_ViewPortAttributes)->p_vSpecificToXD))->p_stCam,&stMatrix); GLI_xLoadMatrix(&stMatrix); GLI_vSetFog(100,100,&ColBidon); p_stPointListEnd=p_stPointList+p_BezierObject->ucSamplingRate; for (;p_stPointListp_ViewPortAttributes), p_stPointList, p_stPointList+1, p_BezierObject->color); } GLI_xPopMatrix(); } /*========================================================== Function name: fn_vBezierObject_ChangeParams Description: Changes the parameters of a bezier objet and recalculates the coordinates of the points. Input: p_BezierObject: Pointer to a pre-created bezier object p_stStartPoint: Pointer to the start point p_stEndPoint: Pointer to the end Point p_stStartVector:Pointer to the start vector p_stEndVector: Pointer to the end vector Output: none Author: Yann Le Tensorer Date: 28 january 1997 Revision: Notes: If an input parameter is 0, this parameter is simply not affected. This enables to change easily only one parameter ==========================================================*/ void fn_vBezierObject_ChangeParams(tdstBezierObject *p_BezierObject, MTH3D_tdstVector* p_stStartPoint, MTH3D_tdstVector* p_stEndPoint, MTH3D_tdstVector* p_stStartVector, MTH3D_tdstVector* p_stEndVector) { if (p_BezierObject==0) return; /* avoid crash */ /* copies input parameters into objects parameters */ if (p_stStartPoint!=0) p_BezierObject->stStartPoint =*p_stStartPoint; if (p_stEndPoint!=0) p_BezierObject->stEndPoint =*p_stEndPoint; if (p_stStartVector!=0) p_BezierObject->stStartVector =*p_stStartVector; if (p_stEndVector!=0) p_BezierObject->stEndVector =*p_stEndVector; fn_vBezierObject_Calculate(p_BezierObject); } /*========================================================== Function name: fn_xBezierObject_GetSpeed Description: returns the speed at a given sample (n° of the point) of a bezier object Input: p_stDynaParam: pointer to a pre-created tdstDynaParam structure ucSampleNo: n° of the point to get the speed from. Output: return value is the speed. Author: Yann Le Tensorer Date: 03 february 1997 Revision: ==========================================================*/ MTH_tdxReal fn_xBezierObject_GetSpeed(tdstBezierObject *p_BezierObject,unsigned char ucSampleNo) { if (p_BezierObject==0) return 0; return fn_xDynamicObject_GetSpeed(p_BezierObject->p_stDynaParams,ucSampleNo); } /*========================================================== Function name: fn_vBezierObject_GetPoint Description: returns the coordinates in the global repère of the point at a given sample (n° of the point) of a bezier object. Input: p_stDynaParam: pointer to a pre-created tdstDynaParam structure ucSampleNo: n° of the point to get the coordinates from. p_ReturnVector: pointer to a vector to be returned. Output: *p_ReturnVector is a vector countaining the.coordinates of the point. Author: Yann Le Tensorer Date: 03 february 1997 Revision: ==========================================================*/ void fn_vBezierObject_GetPoint(tdstBezierObject *p_BezierObject,unsigned char ucSampleNo,MTH3D_tdstVector* p_ReturnVector) { MTH3D_tdstVector *p_stPointList; if (p_BezierObject==0) return; if (p_BezierObject->ucObjectMode==C_ucModeRealObject) p_stPointList=((p_BezierObject->hObject) -> d_stListOfPoints); else p_stPointList=(p_BezierObject->d_stListOfPoints); if (p_stPointList!=0) *p_ReturnVector=p_stPointList[ucSampleNo]; } /*========================================================== Function name: fn_vBezierObject_GetParams Description: Gets the parameters of a bezier objet Input: p_BezierObject: Pointer to a pre-created bezier object p_stStartPoint: Pointer to the start point p_stEndPoint: Pointer to the end Point p_stStartVector:Pointer to the start vector p_stEndVector: Pointer to the end vector Output: *p_stStartPoint:start point *p_stEndPoint: end Point *p_stStartVectorstart vector *p_stEndVector: end vector Author: Yann Le Tensorer Date: 4 february 1997 Revision: Notes: If an input pointer is null, this parameter is simply not affected. ==========================================================*/ void fn_vBezierObject_GetParams(tdstBezierObject *p_BezierObject, MTH3D_tdstVector* p_stStartPoint, MTH3D_tdstVector* p_stEndPoint, MTH3D_tdstVector* p_stStartVector, MTH3D_tdstVector* p_stEndVector) { if (p_BezierObject==0) return; /* avoid crash */ if (p_stStartPoint!=0) *p_stStartPoint = p_BezierObject->stStartPoint; if (p_stEndPoint!=0) *p_stEndPoint = p_BezierObject->stEndPoint; if (p_stEndVector!=0) *p_stEndVector = p_BezierObject->stEndVector; if (p_stStartVector!=0) *p_stStartVector= p_BezierObject->stStartVector; } /*========================================================== Function name: fn_ucBezierObject_GetSamplingRate Description: Gets the sampling rate of a BezierObject objet Input: p_BezierObject: Pointer to a pre-created Bezier object Output: return value is the sampling rate of the circle arc object Author: Yann Le Tensorer Date: 5 february 1997 Revision: ==========================================================*/ unsigned char fn_ucBezierObject_GetSamplingRate(tdstBezierObject *p_BezierObject) { if (p_BezierObject==0) return 0; else return p_BezierObject->ucSamplingRate; }