reman3/Rayman_X/cpa/tempgrp/Owp/src/Bezier.c

528 lines
17 KiB
C
Raw Blame History

/*=========================================================================================
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;xCurVertex<ucSamplingRate;xCurVertex++)
{
/* define start and end vertex of a line */
xLineDoubleIndex.a2_xIndex[0]=xCurVertex;
xLineDoubleIndex.a2_xIndex[1]=xCurVertex+1;
/* set line index */
GEO_xSetIndexOfElementLines(p_BezierObject->hObject,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_stPointList<p_stPointListEnd;p_stPointList++)
{
GLI_xDraw3DLine16(
(struct GLD_tdstViewportAttributes_*)(p_BezierObject->p_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<65>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;
}