33 #include <libFreeWRL.h>
35 #include "../vrml_parser/Structs.h"
36 #include "../main/headers.h"
38 #include "Collision.h"
39 #include "LinearAlgebra.h"
40 #include "../opengl/Frustum.h"
41 #include "../opengl/Material.h"
42 #include "Component_Geometry3D.h"
43 #include "../opengl/OpenGL_Utils.h"
44 #include "../opengl/Textures.h"
46 #include "Component_Shape.h"
47 #include "../scenegraph/RenderFuncs.h"
48 #include "../vrml_parser/CRoutes.h"
51 #if defined(_MSC_VER) && _MSC_VER < 1500
60 void *Component_NURBS_constructor(){
65 void Component_NURBS_init(
struct tComponent_NURBS *t){
68 t->prv = Component_NURBS_constructor();
182 rep->transparency = 0;
184 glDeleteBuffers(VBO_COUNT, rep->VBO_buffers);
185 FREE_IF_NZ(rep->actualCoord);
186 FREE_IF_NZ(rep->cindex);
187 FREE_IF_NZ(rep->colindex);
188 FREE_IF_NZ(rep->GeneratedTexCoords[0]);
189 FREE_IF_NZ(rep->norindex);
190 FREE_IF_NZ(rep->normal);
191 FREE_IF_NZ(rep->tcindex);
208 polyrep->streamed = FALSE;
211 polyrep->minVals[0] = 999999.9f;
212 polyrep->minVals[1] = 999999.9f;
213 polyrep->minVals[2] = 999999.9f;
214 polyrep->maxVals[0] = -999999.9f;
215 polyrep->maxVals[1] = -999999.9f;
216 polyrep->maxVals[2] = -999999.9f;
218 for (i=0; i<VBO_COUNT; i++)
219 polyrep->VBO_buffers[i] = 0;
222 glGenBuffers(1,&polyrep->VBO_buffers[VERTEX_VBO]);
223 glGenBuffers(1,&polyrep->VBO_buffers[INDEX_VBO]);
238 int uniformKnot(
int n,
int p,
float *U){
243 uniform = 1.0f/(float)(n-p);
244 for(j=0;j<p;k++,j++){
248 for(j=0;j<mm;j++,k++){
251 for(j=0;j<p;j++,k++){
257 printf(
" U[%d]=%f",j,U[j]);
263 int FindSpan(
int n,
int p,
float u,
float *U)
291 int i, span, m, order;
297 if(u >= U[i] && u < U[i+1])
304 if(u == U[n])
return n-1;
305 low = p; high = n+1; mid = (low+high)/2;
306 while(u < U[mid] || u >= U[mid+1]){
307 if(u < U[mid]) high = mid;
309 mid = (low + high)/2;
315 int BasisFuns(
int span,
float u,
int p,
float *U,
float *N){
328 float left[5], right[5], saved, temp;
332 left[j] = u - U[span+1 - j];
333 right[j] = U[span+j] - u;
339 temp = N[r]/(right[r+1]+left[j-r]);
340 N[r] = saved + right[r+1]*temp;
341 saved = left[j-r]*temp;
349 int CurvePoint(
int n,
int p,
float* U,
float *Pw,
float u,
float *C )
370 span = FindSpan(n,p,u,U);
371 BasisFuns(span,u,p,U,N);
373 for(i=0;i<4;i++) Cw[i] = 0.0f;
377 Cw[i] += N[j]*Pw[(span-p+j)*4 + i];
396 int SurfacePoint(
int n,
int p,
float *U,
397 int m,
int q,
float *V,
398 float *Pw,
float u,
float v,
float *S)
417 int uspan, vspan, i, l, k;
418 float Nu[100], Nv[100], temp[6][4], Sw[4];
420 uspan = FindSpan(n,p,u,U);
421 BasisFuns(uspan,u,p,U,Nu);
422 vspan = FindSpan(m,q,v,V);
423 BasisFuns(vspan,v,q,V,Nv);
430 temp[l][i] += Nu[k]*Pw[((uspan-p+k)*n + (vspan-q+l))*4 + i];
434 for(i=0;i<4;i++) Sw[i] = 0.0f;
437 Sw[i] += Nv[l]*temp[l][i];
445 #include <libnurbs2.h>
447 static int DEBGC = 0;
453 #define NNC(A) NNC0(X3D_NODE(A)) //node needs compiling
454 #define MNC(A) MNC0(X3D_NODE(A)) //mark node compiled
455 #define MNX(A) MNX0(X3D_NODE(A)) //mark node changed
456 #define PPX(A) getTypeNode(X3D_NODE(A)) //possible proto expansion
458 void CALLBACK nurbsError(GLenum errorCode)
464 printf(
"ouch from nurbsError\n");
469 void CALLBACK nurbscurveBegincb(GLenum type,
void *ud)
472 if(DEBGC) printf(
"nurbscurveBegin\n");
474 void CALLBACK nurbscurveVertexcb(GLfloat *vertex,
void *ud)
479 ns = node->__points.n;
480 np = node->__numPoints;
483 node->__points.p = REALLOC(node->__points.p,ns *
sizeof(
struct SFVec3f));
484 node->__points.n = ns;
486 pp = &node->__points.p[np];
488 pp->c[i] = vertex[i];
489 node->__numPoints ++;
491 if(DEBGC) printf(
"nurbscurveVertex\n");
493 void CALLBACK nurbscurveNormalcb(GLfloat *nml,
void *ud)
496 if(DEBGC) printf(
"nurbscurveNormal\n");
498 void CALLBACK nurbscurveEndcb(
void *ud)
502 if(DEBGC) printf(
"nurbscurveEnd\n");
507 int generateUniformKnotVector(
int order,
int ncontrol,
float *knots){
523 m = ncontrol - order;
525 uniform = 1.0f/(float)(m + 1);
526 for(j=0;j<order;k++,j++){
529 for(j=0;j<m;j++,k++){
530 knots[k] =uniform*(float)(j+1);
532 for(j=0;j<order;j++,k++){
537 int knotsOK(
int order,
int ncontrol,
int nknots,
double *knots){
540 if(nknots < 2 || nknots != ncontrol + order )
544 double lastval = knots[0];
545 for(i=1;i<nknots;i++){
546 if(lastval == knots[i]) nconsec++;
550 if(knots[i] < lastval)
558 int knotsOKf(
int order,
int ncontrol,
int nknots,
float *knots){
561 if(nknots < 2 || nknots != ncontrol + order )
565 double lastval = knots[0];
566 for(i=1;i<nknots;i++){
567 if(lastval == knots[i]) nconsec++;
571 if(knots[i] < lastval)
581 if(node->point.n && !node->controlPoint.n){
584 node->controlPoint.p = MALLOC(
struct SFVec2d*,node->point.n *
sizeof(
struct SFVec2d));
585 for(i=0;i<node->point.n;i++)
586 float2double(node->controlPoint.p[i].c,node->point.p[i].c,2);
594 GLfloat *xyzw, *knots;
597 if(node->controlPoint){
598 if(node->controlPoint->_nodeType == NODE_CoordinateDouble){
602 xyzw = MALLOC(
void *, n * 4 *
sizeof(GLfloat));
603 for(i=0;i<mfd->n;i++){
605 xyzw[i*4 + j] = (float) mfd->p[i].c[j];
608 }
else if(node->controlPoint->_nodeType == NODE_Coordinate){
612 xyzw = MALLOC(
void *, n * 4 *
sizeof(GLfloat));
613 for(i=0;i<mff->n;i++){
615 xyzw[i*4 + j] = mff->p[i].c[j];
622 if(node->weight.n && node->weight.n == n){
625 m = min(node->weight.n, n);
627 im = i < m ? i : m-1;
628 w = node->weight.p[im];
629 xyzw[i*4 + 3] = (float)w;
632 for(i=0;i<n;i++) xyzw[i*4 + 3] = 1.0;
635 if(knotsOK(node->order,n,node->knot.n,node->knot.p)){
638 knots = MALLOC(
void *, nk *
sizeof(GLfloat));
640 knots[i] = (GLfloat)node->knot.p[i];
649 nk = n + node->order ;
651 knots = MALLOC(
void *, nk *
sizeof(GLfloat));
652 generateUniformKnotVector(node->order,n, knots);
655 printf(
"bad knot vector, replacing with:\n");
657 printf(
"[%d]=%f \n",ii,knots[ii]);
663 if(n && nk && nk >= n){
666 mtess = node->order + 1;
667 ntess = node->tessellation;
668 theNurb = gluNewNurbsRenderer();
669 gluNurbsProperty(theNurb, GLU_NURBS_MODE, GLU_NURBS_TESSELLATOR);
670 gluNurbsCallbackData(theNurb,(GLvoid*)node);
676 double model[16], proj[16];
677 float modelf[16], projf[16];
683 node->__points.p = MALLOC(
void *,
sizeof(
struct SFVec3f)*n*10);
684 node->__points.n = n*10;
686 gluNurbsProperty(theNurb, GLU_SAMPLING_TOLERANCE, (
float)(mtess));
688 gluNurbsProperty(theNurb,GLU_SAMPLING_METHOD,GLU_PATH_LENGTH);
690 gluNurbsProperty(theNurb,GLU_SAMPLING_METHOD,GLU_PARAMETRIC_TOLERANCE);
691 gluNurbsProperty(theNurb, GLU_AUTO_LOAD_MATRIX,GL_FALSE);
693 FW_GL_GETDOUBLEV(GL_MODELVIEW_MATRIX, model);
694 FW_GL_GETDOUBLEV(GL_PROJECTION_MATRIX, proj);
695 FW_GL_GETINTEGERV(GL_VIEWPORT, viewPort);
697 modelf[i] = (float)model[i];
698 projf[i] = (float)proj[i];
700 gluLoadSamplingMatrices(theNurb,modelf,projf,viewPort);
707 mtess = max(mtess,ntess+1);
709 mtess = max(mtess,(-ntess * n) + 1);
711 mtess = max(mtess,2*n + 1);
712 mtess = (int)((
float)mtess * node->_tscale);
713 node->__points.p = MALLOC(
void *,
sizeof(
struct SFVec3f)*mtess+1);
714 node->__points.n = mtess;
715 gluNurbsProperty(theNurb,GLU_SAMPLING_METHOD,GLU_DOMAIN_DISTANCE);
716 gluNurbsProperty(theNurb,GLU_U_STEP,(GLfloat)mtess);
718 gluNurbsProperty(theNurb, GLU_DISPLAY_MODE, GLU_FILL);
719 gluNurbsCallback(theNurb, GLU_ERROR, nurbsError);
720 gluNurbsCallback(theNurb, GLU_NURBS_BEGIN_DATA, nurbscurveBegincb);
721 gluNurbsCallback(theNurb, GLU_NURBS_VERTEX_DATA, nurbscurveVertexcb);
722 gluNurbsCallback(theNurb, GLU_NURBS_NORMAL_DATA, nurbscurveNormalcb);
723 gluNurbsCallback(theNurb, GLU_NURBS_END_DATA, nurbscurveEndcb);
724 gluBeginCurve(theNurb);
725 node->__numPoints = 0;
726 gluNurbsCurve(theNurb,nk,knots,4,xyzw,node->order,GL_MAP1_VERTEX_4);
727 gluEndCurve(theNurb);
728 gluDeleteNurbsRenderer(theNurb);
729 node->__points.n = node->__numPoints;
738 if (node->__numPoints>0) {
740 setExtent( node->EXTENT_MAX_X, node->EXTENT_MIN_X,
741 node->EXTENT_MAX_Y, node->EXTENT_MIN_Y, 0.0f,0.0f,X3D_NODE(node));
748 FW_GL_VERTEX_POINTER (3,GL_FLOAT,0,(GLfloat *)node->__points.p);
749 sendArraysToGPU (GL_LINE_STRIP, 0, node->__numPoints);
750 tg->Mainloop.trisThisLoop += node->__numPoints;
756 int nc, nu, nku, nkv, nv, i,j;
757 float *knotsu, *knotsv, *xyzw;
760 mff = &node->controlPoint;
762 xyzw = MALLOC(
void *, nc * 4 *
sizeof(GLfloat));
763 for(i=0;i<mff->n;i++){
765 xyzw[i*4 + j] = mff->p[i].c[j];
767 xyzw[i*4 + 2] = 0.0f;
768 xyzw[i*4 + 3] = 1.0f;
770 nu = node->uDimension;
771 nv = node->vDimension;
772 if(node->weight.n && node->weight.n == nc){
775 m = min(node->weight.n, nc);
777 im = i < m ? i : m-1;
778 w = node->weight.p[im];
779 xyzw[i*4 + 3] = (float) w;
782 for(i=0;i<nc;i++) xyzw[i*4 + 3] = 1.0;
784 nu = node->uDimension;
785 nv = node->vDimension;
788 if(knotsOK(node->uOrder,nu,node->uKnot.n,node->uKnot.p)){
792 knotsu = MALLOC(
void *, nku *
sizeof(GLfloat));
794 knotsu[i] = (GLfloat)node->uKnot.p[i];
798 printf(
"good u knot vector nk=%d\n",nku);
799 for(ii=0;ii<nku;ii++)
800 printf(
"[%d]=%f \n",ii,knotsu[ii]);
806 nku = nu + node->uOrder ;
808 knotsu = MALLOC(
void *, nku *
sizeof(GLfloat));
809 generateUniformKnotVector(node->uOrder,nu, knotsu);
812 printf(
"bad u knot vector given, replacing with:\n");
813 for(ii=0;ii<nku;ii++)
814 printf(
"[%d]=%f \n",ii,knotsu[ii]);
820 if(knotsOK(node->vOrder,nv,node->vKnot.n,node->vKnot.p)){
823 knotsv = MALLOC(
void *, nkv *
sizeof(GLfloat));
825 knotsv[i] = (GLfloat)node->vKnot.p[i];
829 printf(
"good v knot vector nk=%d\n",nkv);
830 for(ii=0;ii<nkv;ii++)
831 printf(
"[%d]=%f \n",ii,knotsv[ii]);
837 nkv = nv + node->vOrder ;
839 knotsv = MALLOC(
void *, nkv *
sizeof(GLfloat));
840 generateUniformKnotVector(node->vOrder,nv, knotsv);
843 printf(
"bad v knot vector given, replacing with:\n");
844 for(ii=0;ii<nkv;ii++)
845 printf(
"[%d]=%f \n",ii,knotsv[ii]);
848 if(!knotsOKf(node->vOrder,nv,nkv,knotsv))
849 printf(
"ouch still not right knot vector\n");
852 node->_uKnot.p = knotsu;
853 node->_uKnot.n = nku;
854 node->_vKnot.p = knotsv;
855 node->_vKnot.n = nkv;
856 node->_controlPoint.p = (
struct SFVec4f*)xyzw;
857 node->_controlPoint.n = nc;
861 int getNurbsSurfacePoint(
struct X3D_Node *nurbsSurfaceNode,
float *uv,
float *xyz){
863 if(nurbsSurfaceNode){
864 switch(nurbsSurfaceNode->_nodeType){
865 case NODE_NurbsTextureCoordinate:
868 if(NNC(node)) compile_NurbsTextureCoordinate(node);
869 ret = SurfacePoint( node->uDimension,node->uOrder-1,node->_uKnot.p,
870 node->vDimension,node->vOrder-1,node->_vKnot.p,
871 (
float *)node->_controlPoint.p,uv[0],uv[1],xyz);
874 case NODE_NurbsPatchSurface:
876 case NODE_NurbsTrimmedSurface:
916 void CALLBACK nurbssurfBegincb(GLenum type,
void *ud)
918 struct stripState ss;
920 if(0)
if(DEBG) printf(
"callback nurbsSurfaceBegin\n");
922 printf(
"nurbssurfBegin type = ");
924 case GL_QUAD_STRIP: printf(
"QUAD_STRIP");
break;
925 case GL_TRIANGLE_STRIP: printf(
"TRIANGLE_STRIP");
break;
926 case GL_TRIANGLE_FAN: printf(
"TRIANGLE_FAN");
break;
927 case GL_TRIANGLES: printf(
"TRIANGLES");
break;
929 printf(
"not sure %x %d",type,type);
943 vector_pushBack(
struct stripState,strips,ss);
945 void CALLBACK nurbssurfVertexcb(GLfloat *vertex,
void *ud)
947 struct stripState *ss;
950 ss = vector_get_ptr(
struct stripState,strips,strips->n -1);
951 memcpy(&pp,vertex,
sizeof(
struct SFVec3f));
952 vector_pushBack(
struct SFVec3f,&ss->pv,pp);
955 if(0) printf(
"callback nurbssurfVertex %f %f %f\n",vertex[0],vertex[1],vertex[2]);
957 void CALLBACK nurbssurfNormalcb(GLfloat *nml,
void *ud)
959 struct stripState *ss;
962 ss = vector_get_ptr(
struct stripState,strips,strips->n -1);
963 memcpy(&pp,nml,
sizeof(
struct SFVec3f));
964 vector_pushBack(
struct SFVec3f,&ss->nv,pp);
967 if(0) printf(
"callback nurbssurfNormal\n");
969 void CALLBACK nurbssurfEndcb(
void *ud)
971 struct stripState *ss;
973 ss = vector_get_ptr(
struct stripState,strips,strips->n -1);
976 printf(
"nurbssurfEnd #p %d #n %d\n",ss->pv.n, ss->nv.n);
977 for(i=0;i<ss->pv.n;i++){
979 printf(
"%f %f %f\n",pp.c[0],pp.c[1],pp.c[2]);
982 if(0)
if(DEBG) printf(
"callback nurbsSurfaceEnd\n");
985 void CALLBACK nurbssurfTexcoordcb(GLfloat *tCrd,
void *ud){
986 static int count = 0;
987 struct stripState *ss;
990 ss = vector_get_ptr(
struct stripState,strips,strips->n -1);
991 memcpy(&tp,tCrd,
sizeof(
struct SFVec2f));
992 vector_pushBack(
struct SFVec2f,&ss->tv,tp);
999 printf(
"callback nurbssufTexcoordcb\n");
1004 #define GL_QUAD_STRIP 0x0008
1006 static int USETXCOORD = 1;
1010 int i, j, npoints, np, ni, ntri, nindex, ntc;
1011 struct stripState *ss;
1014 GLuint *cindex, *norindex, *tcindex;
1015 float *tcoord = NULL;
1023 polyrep = node->_intern;
1024 FREE_IF_NZ(polyrep->cindex);
1025 FREE_IF_NZ(polyrep->actualCoord);
1026 FREE_IF_NZ(polyrep->GeneratedTexCoords[0]);
1027 FREE_IF_NZ(polyrep->colindex);
1028 FREE_IF_NZ(polyrep->color);
1029 FREE_IF_NZ(polyrep->norindex);
1030 FREE_IF_NZ(polyrep->normal);
1031 FREE_IF_NZ(polyrep->flat_normal);
1032 FREE_IF_NZ(polyrep->tcindex);
1033 FREE_IF_NZ(polyrep->wire_indices);
1037 node->_intern = create_polyrep();
1039 rep_ = polyrep = node->_intern;
1050 rep_->ntexdim[0] = 2;
1051 rep_->tcoordtype = NODE_TextureCoordinate;
1056 npoints = nindex = ntc = 0;
1057 for(i=0;i<strips->n;i++){
1058 ss = vector_get_ptr(
struct stripState,strips,i);
1059 npoints += ss->pv.n;
1062 case GL_QUAD_STRIP: nindex += (ss->pv.n -2)/2 * 5;
break;
1063 case GL_TRIANGLE_STRIP: nindex += (ss->pv.n -2);
break;
1064 case GL_TRIANGLE_FAN: nindex += (ss->pv.n -2);
break;
1065 case GL_TRIANGLES: nindex += (ss->pv.n -2);
break;
1067 nindex += (ss->pv.n -2);
1073 rep_->actualCoord = MALLOC(
void *, npoints * 3 *
sizeof(
float));
1074 rep_->normal = MALLOC(
void *, npoints * 3 *
sizeof(
float));
1082 rep_->ntri = ntri = nindex;
1086 cindex = rep_->cindex = MALLOC(GLuint *,
sizeof(GLuint)*3*(ntri));
1087 norindex = rep_->norindex = MALLOC(GLuint *,
sizeof(GLuint)*3*ntri);
1089 tcindex = rep_->tcindex = MALLOC(GLuint*,
sizeof(GLuint)*3*(ntri));
1094 tcoord = MALLOC (
float *,
sizeof (
float) * ntri * 2 * 3);
1101 for(i=0;i<strips->n;i++){
1102 ss = vector_get_ptr(
struct stripState,strips,i);
1104 memcpy(&rep_->actualCoord[np*3],ss->pv.data,ss->pv.n * 3 *
sizeof(
float));
1105 memcpy(&rep_->normal[np*3],ss->nv.data,ss->nv.n * 3 *
sizeof(
float));
1106 if(USETXCOORD && tcoord) memcpy(&tcoord[np*2],ss->tv.data,ss->tv.n * 2 *
sizeof(
float));
1109 for(j=0;j<ss->pv.n -2;j+=2){
1110 rep_->cindex[ni++] = np+j;
1111 rep_->cindex[ni++] = np+j+1;
1112 rep_->cindex[ni++] = np+j+3;
1114 rep_->cindex[ni++] = np+j+3;
1115 rep_->cindex[ni++] = np+j+2;
1116 rep_->cindex[ni++] = np+j;
1119 memcpy(&rep_->norindex[ntri*3],&rep_->cindex[ntri*3],2*3*
sizeof(
int));
1120 if(USETXCOORD) memcpy(&rep_->tcindex[ntri*3],&rep_->cindex[ntri*3],2*3*
sizeof(
int));
1124 case GL_TRIANGLE_STRIP:
1125 nindex += (ss->pv.n -2);
1127 case GL_TRIANGLE_FAN:
1129 for(j=0;j<ss->pv.n -2;j+=1){
1130 rep_->cindex[ni++] = np;
1131 rep_->cindex[ni++] = np+j+1;
1132 rep_->cindex[ni++] = np+j+2;
1133 memcpy(&rep_->norindex[ntri*3],&rep_->cindex[ntri*3],3*
sizeof(
int));
1134 if(USETXCOORD) memcpy(&rep_->tcindex[ntri*3],&rep_->cindex[ntri*3],3*
sizeof(
int));
1139 nindex += (ss->pv.n -2);
1142 nindex += (ss->pv.n -2);
1147 if(node->texCoord && node->texCoord->_nodeType == NODE_NurbsTextureCoordinate){
1148 static FILE *fp = NULL;
1154 xyz[0] = tcoord[i*2 + 1];
1155 xyz[1] = tcoord[i*2 + 0];
1157 xyz[3] = tcoord[i*2 + 3];
1158 getNurbsSurfacePoint(node->texCoord, xyz, stru);
1160 tcoord[i*2 + 0] = stru[0];
1161 tcoord[i*2 + 1] = stru[1];
1171 tcnode->point.p = (
struct SFVec2f*)tcoord;
1172 tcnode->point.n = np;
1173 if(0)
for(i=0;i<tcnode->point.n;i++){
1174 printf(
"%d %f %f\n",i,tcnode->point.p[i].c[0],tcnode->point.p[i].c[1]);
1182 if (polyrep->ntri != 0) {
1184 stream_polyrep(node, NULL,NULL,NULL,NULL, tcnode);
1187 FREE_IF_NZ(tcnode->point.p);
1190 polyrep->irep_change = node->_change;
1215 int i,j, n, nu, nv, nku, nkv;
1216 GLfloat *xyzw, *knotsu, *knotsv;
1219 nku = nkv = nu = nv = n = 0;
1220 xyzw = knotsu = knotsv = NULL;
1227 if(node->controlPoint){
1228 if(node->controlPoint->_nodeType == NODE_CoordinateDouble){
1232 xyzw = MALLOC(
void *, n * 4 *
sizeof(GLfloat));
1233 for(i=0;i<mfd->n;i++){
1235 xyzw[i*4 + j] = (float)mfd->p[i].c[j];
1238 }
else if(node->controlPoint->_nodeType == NODE_Coordinate){
1242 xyzw = MALLOC(
void *, n * 4 *
sizeof(GLfloat));
1243 for(i=0;i<mff->n;i++){
1245 xyzw[i*4 + j] = mff->p[i].c[j];
1252 if(node->weight.n && node->weight.n == n){
1255 m = min(node->weight.n, n);
1257 im = i < m ? i : m-1;
1258 w = node->weight.p[im];
1259 xyzw[i*4 + 3] = (float)w;
1262 for(i=0;i<n;i++) xyzw[i*4 + 3] = 1.0;
1264 nu = node->uDimension;
1265 nv = node->vDimension;
1268 if(knotsOK(node->uOrder,nu,node->uKnot.n,node->uKnot.p)){
1271 nku = node->uKnot.n;
1272 knotsu = MALLOC(
void *, nku *
sizeof(GLfloat));
1274 knotsu[i] = (GLfloat)node->uKnot.p[i];
1278 printf(
"good u knot vector nk=%d\n",nku);
1279 for(ii=0;ii<nku;ii++)
1280 printf(
"[%d]=%f \n",ii,knotsu[ii]);
1285 static int once = 0;
1286 nku = nu + node->uOrder ;
1288 knotsu = MALLOC(
void *, nku *
sizeof(GLfloat));
1289 generateUniformKnotVector(node->uOrder,nu, knotsu);
1292 printf(
"bad u knot vector given, replacing with:\n");
1293 for(ii=0;ii<nku;ii++)
1294 printf(
"[%d]=%f \n",ii,knotsu[ii]);
1300 if(knotsOK(node->vOrder,nv,node->vKnot.n,node->vKnot.p)){
1302 nkv = node->vKnot.n;
1303 knotsv = MALLOC(
void *, nkv *
sizeof(GLfloat));
1305 knotsv[i] = (GLfloat)node->vKnot.p[i];
1309 printf(
"good v knot vector nk=%d\n",nkv);
1310 for(ii=0;ii<nkv;ii++)
1311 printf(
"[%d]=%f \n",ii,knotsv[ii]);
1315 static int once = 0;
1317 nkv = nv + node->vOrder ;
1319 knotsv = MALLOC(
void *, nkv *
sizeof(GLfloat));
1320 generateUniformKnotVector(node->vOrder,nv, knotsv);
1323 printf(
"bad v knot vector given, replacing with:\n");
1324 for(ii=0;ii<nkv;ii++)
1325 printf(
"[%d]=%f \n",ii,knotsv[ii]);
1331 if(n && nku && nkv){
1333 int ntessu, ntessv, mtessu, mtessv;
1336 int texcoordnodeIsGenerated;
1338 mtessu = node->uOrder + 1;
1339 ntessu = node->uTessellation;
1340 mtessv = node->vOrder + 1;
1341 ntessv = node->vTessellation;
1343 if(DEBG) printf(
"gluNewNurbsRenderer\n");
1345 theNurb = gluNewNurbsRenderer();
1346 gluNurbsProperty(theNurb, GLU_NURBS_MODE, GLU_NURBS_TESSELLATOR);
1352 double model[16], proj[16];
1353 float modelf[16], projf[16];
1360 gluNurbsProperty(theNurb, GLU_SAMPLING_TOLERANCE, (
float)(mtessu));
1362 gluNurbsProperty(theNurb,GLU_SAMPLING_METHOD,GLU_PATH_LENGTH);
1364 gluNurbsProperty(theNurb,GLU_SAMPLING_METHOD,GLU_PARAMETRIC_TOLERANCE);
1365 gluNurbsProperty(theNurb, GLU_AUTO_LOAD_MATRIX,GL_FALSE);
1367 FW_GL_GETDOUBLEV(GL_MODELVIEW_MATRIX, model);
1368 FW_GL_GETDOUBLEV(GL_PROJECTION_MATRIX, proj);
1369 FW_GL_GETINTEGERV(GL_VIEWPORT, viewPort);
1371 modelf[i] = (float)model[i];
1372 projf[i] = (float)proj[i];
1374 gluLoadSamplingMatrices(theNurb,modelf,projf,viewPort);
1381 mtessu = max(mtessu,ntessu+1);
1383 mtessu = max(mtessu,(-ntessu * nu) + 1);
1385 mtessu = max(mtessu,2*nu + 1);
1388 mtessv = max(mtessv,ntessv+1);
1390 mtessv = max(mtessv,(-ntessv * nv) + 1);
1392 mtessv = max(mtessv,2*nv + 1);
1393 mtessu = (int)((
float)mtessu * node->_tscale);
1394 mtessv = (int)((
float)mtessv * node->_tscale);
1396 gluNurbsProperty(theNurb,GLU_SAMPLING_METHOD,GLU_DOMAIN_DISTANCE);
1397 gluNurbsProperty(theNurb,GLU_U_STEP,(GLfloat)mtessu);
1398 gluNurbsProperty(theNurb,GLU_V_STEP,(GLfloat)mtessv);
1400 gluNurbsProperty(theNurb, GLU_DISPLAY_MODE, GLU_FILL);
1402 gluNurbsCallback(theNurb, GLU_ERROR, nurbsError);
1403 gluNurbsCallback(theNurb, GLU_NURBS_BEGIN_DATA, nurbssurfBegincb);
1404 gluNurbsCallback(theNurb, GLU_NURBS_VERTEX_DATA, nurbssurfVertexcb);
1405 gluNurbsCallback(theNurb, GLU_NURBS_NORMAL_DATA, nurbssurfNormalcb);
1406 gluNurbsCallback(theNurb, GLU_NURBS_END_DATA, nurbssurfEndcb);
1407 gluNurbsCallback(theNurb, GLU_NURBS_TEXTURE_COORD_DATA, nurbssurfTexcoordcb);
1409 strips = newVector(
struct stripState,20);
1410 gluNurbsCallbackData(theNurb,(GLvoid*)strips);
1412 if(DEBG) printf(
"gluBeginSurface \n");
1413 gluBeginSurface(theNurb);
1414 gluNurbsSurface(theNurb,nku,knotsu,nkv,knotsv,4,4*nu,xyzw,node->uOrder,node->vOrder,GL_MAP2_VERTEX_4);
1448 texcoordnodeIsGenerated = FALSE;
1449 texCoordNode = node->texCoord;
1459 float du, dv, uu, vv;
1462 texcoordnodeIsGenerated = TRUE;
1463 texCoord->point.p = MALLOC(
struct SFVec2f*,nu * nv *
sizeof(
struct SFVec2f));
1464 du = 1.0f / (float)max(1,(nu -1));
1465 dv = 1.0f / (float)max(1,(nv -1));
1469 if(k == nv-1) vv = 1.0f;
1472 if(j == nu-1) uu = 1.0f;
1473 texCoord->point.p[jj].c[0] = uu;
1474 texCoord->point.p[jj].c[1] = vv;
1480 texCoord->point.n = jj;
1481 texCoordNode = X3D_NODE(texCoord);
1491 if(texCoordNode->_nodeType == NODE_TextureCoordinate){
1494 float *control2D = (
float*)texCoord->point.p;
1495 int nctrl = texCoord->point.n;
1500 gluNurbsSurface(theNurb,nku,knotsu,nkv,knotsv,2,2*nu,control2D,node->uOrder,node->vOrder,GL_MAP2_TEXTURE_COORD_2);
1504 float *tknotsu, *tknotsv;
1507 tknotsu = MALLOC(
float *, (nu+2) *
sizeof(GLfloat));
1508 tknotsv = MALLOC(
float *, (nv+2) *
sizeof(GLfloat));
1509 generateUniformKnotVector(2,nu,tknotsu);
1510 generateUniformKnotVector(2,nv,tknotsv);
1511 printf(
"tknotsu = [");
1512 for(k=0;k<nu+2;k++) printf(
"%f ",tknotsu[k]);
1513 printf(
"]\ntknotsv = [");
1514 for(k=0;k<nv+2;k++) printf(
"%f ",tknotsv[k]);
1516 gluNurbsSurface(theNurb,nu+2,knotsu,nv+2,knotsv,4,4*nu,control2D,2,2,GL_MAP2_TEXTURE_COORD_2);
1518 }
else if(texCoordNode->_nodeType == NODE_NurbsTextureCoordinate){
1525 float tknots[4] = {0.0f, 0.0f, 1.0f, 1.0f};
1526 float unit_control2D [8] = {0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f};
1528 gluNurbsSurface(theNurb,4,tknots,4,tknots,2,2*2,unit_control2D,2,2,GL_MAP2_TEXTURE_COORD_2);
1533 float du, dv, uu, vv;
1537 texcoordnodeIsGenerated = TRUE;
1538 FREE_IF_NZ(texCoord->point.p);
1539 texCoord->point.p = MALLOC(
struct SFVec2f*,nu * nv *
sizeof(
struct SFVec2f));
1540 du = 1.0f / (float)max(1,(nu -1));
1541 dv = 1.0f / (float)max(1,(nv -1));
1545 if(k == nv-1) vv = 1.0f;
1548 if(j == nu-1) uu = 1.0f;
1549 texCoord->point.p[jj].c[0] = uu;
1550 texCoord->point.p[jj].c[1] = vv;
1556 texCoord->point.n = jj;
1557 texCoordNode = X3D_NODE(texCoord);
1561 control2D = (
float*)texCoord->point.p;
1562 gluNurbsSurface(theNurb,nku,knotsu,nkv,knotsv,2,2*nu,control2D,node->uOrder,node->vOrder,GL_MAP2_TEXTURE_COORD_2);
1574 if(DEBG) printf(
"gluBeginTrim \n");
1575 gluBeginTrim (theNurb);
1579 GLfloat edgePt[5][2] = {{0.0, 0.0}, {1.0, 0.0}, {1.0, 1.0}, {0.0, 1.0}, {0.0, 0.0}};
1580 if(DEBG) printf(
"gluPwlCurve 0\n");
1581 gluPwlCurve (theNurb, 5, &edgePt[0][0], 2, GLU_MAP1_TRIM_2);
1585 GLfloat *edges = MALLOC(
void *, (2 * ntessu + 2 * ntessv) *2*
sizeof(GLfloat));
1586 GLfloat uspan, vspan;
1587 uspan = 1.0f/(float)(ntessu -1);
1588 vspan = 1.0f/(float)(ntessv -1);
1589 for(i=0;i<ntessu-1;i++){
1590 edges[i*2 +0] = (float)(i)*uspan;
1591 edges[i*2 +1] = 0.0;
1592 edges[(ntessu+ntessv+i)*2 + 0] = (
float)(ntessu - 1 - i)*uspan;
1593 edges[(ntessu+ntessv+i)*2 + 1] = 1.0;
1595 for(i=0;i<ntessv;i++){
1596 edges[(ntessu+i)*2 + 0] = 1.0;
1597 edges[(ntessu+i)*2 + 1] = (
float)(i)*vspan;
1598 edges[(ntessu+ntessv+ntessu+i)*2 + 0] = 0.0;
1599 edges[(ntessu+ntessv+ntessu+i)*2 + 1] = (
float)(ntessv - 1 - i)*vspan;
1602 edges[((ntessu -1)*2 + (ntessv -1)*2)*2 + 0] = 0.0;
1603 edges[((ntessu -1)*2 + (ntessv -1)*2)*2 + 1] = 0.0;
1604 if(DEBG) printf(
"gluPwlCurve 1\n");
1605 gluPwlCurve (theNurb, 2*(ntessu -1 + ntessv -1) +1, edges, 2, GLU_MAP1_TRIM_2);
1607 if(DEBG) printf(
"gluEndTrim\n");
1608 gluEndTrim (theNurb);
1614 GLfloat curvePt[4][2] =
1615 {{0.25, 0.5}, {0.25, 0.75}, {0.75, 0.75}, {0.75, 0.5}};
1616 GLfloat curveKnots[8] =
1617 {0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0};
1618 GLfloat pwlPt[4][2] =
1619 {{0.75, 0.5}, {0.5, 0.25}, {0.25, 0.5}};
1621 if(DEBG) printf(
"gluBeginTrim A\n");
1622 gluBeginTrim (theNurb);
1623 if(DEBG) printf(
"gluNurbsCurve A\n");
1624 gluNurbsCurve (theNurb, 8, curveKnots, 2,
1625 &curvePt[0][0], 4, GLU_MAP1_TRIM_2);
1626 if(DEBG) printf(
"gluPwlCurve A\n");
1627 gluPwlCurve (theNurb, 3, &pwlPt[0][0], 2, GLU_MAP1_TRIM_2);
1628 if(DEBG) printf(
"gluEndTrim A\n");
1629 gluEndTrim (theNurb);
1632 for(i=0;i<trim->n;i++){
1635 if(DEBG) printf(
"gluBeginTrim B\n");
1636 gluBeginTrim (theNurb);
1637 for(m=0;m<tc->children.n;m++)
1642 struct X3D_Node *ctr = tc->children.p[m];
1643 GLfloat *cknot, *ctrl, *cweight;
1644 cknot = ctrl = cweight = NULL;
1645 switch(ctr->_nodeType){
1646 case NODE_ContourPolyline2D:
1648 ctrl = MALLOC(
void *, cp2d->controlPoint.n * 2*
sizeof(GLfloat));
1649 for(j=0;j<cp2d->controlPoint.n;j++) {
1651 ctrl[j*2 + k] = (
float)cp2d->controlPoint.p[j].c[k];
1653 if(DEBG) printf(
"gluPwlCurve B\n");
1654 gluPwlCurve (theNurb, cp2d->controlPoint.n, ctrl, 2, GLU_MAP1_TRIM_2);
1657 case NODE_NurbsCurve2D:
1660 nk = nc2d->controlPoint.n + nc2d->order;
1661 if(nk == nc2d->knot.n)
1663 cknot = MALLOC(
void *, nk *
sizeof(GLfloat));
1666 cweight = MALLOC(
void *, nc2d->controlPoint.n *
sizeof(GLfloat));
1667 if(nc2d->weight.n == nc2d->controlPoint.n){
1668 for(j=0;j<nc2d->weight.n;j++) cweight[j] = (
float)nc2d->weight.p[j];
1670 for(j=0;j<nc2d->controlPoint.n;j++) cweight[j] = 1.0f;
1673 ctrl = MALLOC(
void *, nc2d->controlPoint.n * dim*
sizeof(GLfloat));
1674 for(j=0;j<nc2d->controlPoint.n;j++) {
1676 ctrl[j*dim + k] = (float)nc2d->controlPoint.p[j].c[k];
1677 if(dim == 3) ctrl[j*dim + k] *= cweight[j];
1679 if(dim == 3) ctrl[j*dim + dim-1] = (float)cweight[j];
1681 if(knotsOK(nc2d->order,nc2d->controlPoint.n,nc2d->knot.n,nc2d->knot.p)){
1683 for(j=0;j<nc2d->knot.n;j++)
1684 cknot[j] = (
float)nc2d->knot.p[j];
1686 generateUniformKnotVector(nc2d->order,nc2d->controlPoint.n,cknot);
1687 printf(
"replacing nurbscurve2D knotvector with:\n");
1689 printf(
"%f ",cknot[j]);
1695 printf(
"knot %d ={",nc2d->knot.n);
1696 for(j=0;j<nc2d->knot.n;j++){
1697 printf(
"%f ",cknot[j]);
1700 printf(
"control %d = {\n",nc2d->controlPoint.n);
1701 for(j=0;j<nc2d->controlPoint.n;j++) {
1702 for(k=0;k<dim;k++) printf(
"%f \n",ctrl[j*dim +k]);
1707 if(DEBG) printf(
"gluNurbsCurve B\n");
1710 mtess = nc2d->order + 1;
1711 ntess = nc2d->tessellation;
1717 double model[16], proj[16];
1718 float modelf[16], projf[16];
1725 gluNurbsProperty(theNurb, GLU_SAMPLING_TOLERANCE, (
float)(mtess));
1727 gluNurbsProperty(theNurb,GLU_SAMPLING_METHOD,GLU_PATH_LENGTH);
1729 gluNurbsProperty(theNurb,GLU_SAMPLING_METHOD,GLU_PARAMETRIC_TOLERANCE);
1730 gluNurbsProperty(theNurb, GLU_AUTO_LOAD_MATRIX,GL_FALSE);
1732 FW_GL_GETDOUBLEV(GL_MODELVIEW_MATRIX, model);
1733 FW_GL_GETDOUBLEV(GL_PROJECTION_MATRIX, proj);
1734 FW_GL_GETINTEGERV(GL_VIEWPORT, viewPort);
1736 modelf[i] = (float)model[i];
1737 projf[i] = (float)proj[i];
1739 gluLoadSamplingMatrices(theNurb,modelf,projf,viewPort);
1746 mtess = max(mtess,ntess+1);
1748 mtess = max(mtess,(-ntess * n) + 1);
1750 mtess = max(mtess,2*n + 1);
1751 gluNurbsProperty(theNurb,GLU_SAMPLING_METHOD,GLU_DOMAIN_DISTANCE);
1752 gluNurbsProperty(theNurb,GLU_U_STEP,(GLfloat)mtess);
1755 gluNurbsCurve (theNurb, nk, cknot, dim, ctrl, nc2d->order, GLU_MAP1_TRIM_2);
1758 ConsoleMessage(
"%s %d",
"unknown trimming contour node",ctr->_nodeType);
1762 FREE_IF_NZ(cweight);
1764 if(DEBG) printf(
"gluEndTrim B\n");
1765 gluEndTrim (theNurb);
1768 if(DEBG) printf(
"gluEndSurface \n");
1769 gluEndSurface(theNurb);
1770 if(DEBG) printf(
"gluDeleteNurbsRenderer \n");
1771 if(0) gluDeleteNurbsRenderer(theNurb);
1776 if(texcoordnodeIsGenerated){
1778 FREE_IF_NZ(texCoord->point.p);
1779 FREE_IF_NZ(texCoordNode);
1783 for(i=0;i<vectorSize(strips);i++){
1784 struct stripState *ss = vector_get_ptr(
struct stripState,strips,i);
1785 FREE_IF_NZ(ss->pv.data); ss->pv.allocn = 0; ss->pv.n = 0;
1786 FREE_IF_NZ(ss->nv.data); ss->nv.allocn = 0; ss->nv.n = 0;
1787 FREE_IF_NZ(ss->tv.data); ss->tv.allocn = 0; ss->tv.n = 0;
1789 FREE_IF_NZ(strips->data); strips->allocn = 0; strips->n = 0;
1800 void render_ray_polyrep(
void *node);
1801 void collide_genericfaceset(
void *node);
1802 void render_polyrep(
void *node);
1806 compile_NurbsSurface(node, NULL);
1810 if (!node->_intern)
return;
1811 render_ray_polyrep(node);
1816 if (!node->_intern)
return;
1817 collide_genericfaceset(node);
1822 if (!node->_intern)
return;
1823 CULL_FACE(node->solid)
1824 render_polyrep(node);
1834 if (!node->_intern)
return;
1835 render_ray_polyrep(node);
1840 if (!node->_intern)
return;
1841 collide_genericfaceset(node);
1846 if (!node->_intern)
return;
1847 CULL_FACE(node->solid)
1848 render_polyrep(node);
1851 void do_NurbsPositionInterpolator (
void *node) {
1865 if(!px->_OK == TRUE){
1867 if(!(px->knot.n > 1))
1869 if(!px->controlPoint )
1871 if(px->controlPoint->_nodeType != NODE_Coordinate)
1874 if(control->point.n < 2)
1876 n = control->point.n;
1878 if(px->weight.n == n)
1879 weight = px->weight.p;
1880 px->_xyzw.p = MALLOC(
struct SFVec4f*,control->point.n *
sizeof(
struct SFVec4f));
1882 for(i=0;i<control->point.n;i++){
1884 wt = weight ? (float)weight[i] : 1.0f;
1885 veccopy3f(xyzw,control->point.p[i].c);
1886 vecscale3f(xyzw,xyzw,wt);
1888 veccopy4f(px->_xyzw.p[i].c,xyzw);
1890 if(knotsOK(px->order,px->_xyzw.n,px->knot.n,px->knot.p)){
1893 knots = MALLOC(
void *, nk *
sizeof(GLfloat));
1895 knots[i] = (GLfloat)px->knot.p[i];
1902 static int once = 0;
1904 nk = n + px->order ;
1906 knots = MALLOC(
void *, nk *
sizeof(GLfloat));
1907 generateUniformKnotVector(px->order,n, knots);
1910 printf(
"bad knot vector, replacing with:\n");
1911 for(ii=0;ii<nk;ii++)
1912 printf(
"[%d]=%f \n",ii,knots[ii]);
1917 px->_knot.p = knots;
1919 px->_knotrange.c[0] = px->_knot.p[0];
1920 px->_knotrange.c[1] = px->_knot.p[px->_knot.n-1];
1928 fraction = max(px->_knotrange.c[0],px->set_fraction);
1929 fraction = min(px->_knotrange.c[1],px->set_fraction);
1930 CurvePoint(px->_xyzw.n, px->order-1, px->_knot.p, (
float*)px->_xyzw.p, fraction, cw );
1931 veccopy3f(px->value_changed.c,cw);
1935 printf(
"do_PositionInt: Position/Vec3f interp, node %u kin %d kvin %d set_fraction %f\n",
1936 node, kin, kvin, px->set_fraction);
1948 void do_NurbsOrientationInterpolator (
void *node) {
1962 if(!px->_OK == TRUE){
1964 if(!(px->knot.n > 1))
1966 if(!px->controlPoint )
1968 if(px->controlPoint->_nodeType != NODE_Coordinate)
1971 if(control->point.n < 2)
1973 n = control->point.n;
1975 if(px->weight.n == n)
1976 weight = px->weight.p;
1977 px->_xyzw.p = MALLOC(
struct SFVec4f*,control->point.n *
sizeof(
struct SFVec4f));
1979 for(i=0;i<control->point.n;i++){
1981 wt = weight ? (float)weight[i] : 1.0f;
1982 veccopy3f(xyzw,control->point.p[i].c);
1983 vecscale3f(xyzw,xyzw,wt);
1985 veccopy4f(px->_xyzw.p[i].c,xyzw);
1987 if(knotsOK(px->order,px->_xyzw.n,px->knot.n,px->knot.p)){
1990 knots = MALLOC(
void *, nk *
sizeof(GLfloat));
1992 knots[i] = (GLfloat)px->knot.p[i];
1999 static int once = 0;
2001 nk = n + px->order ;
2003 knots = MALLOC(
void *, nk *
sizeof(GLfloat));
2004 generateUniformKnotVector(px->order,n, knots);
2007 printf(
"bad knot vector, replacing with:\n");
2008 for(ii=0;ii<nk;ii++)
2009 printf(
"[%d]=%f \n",ii,knots[ii]);
2014 px->_knot.p = knots;
2016 px->_knotrange.c[0] = px->_knot.p[0];
2017 px->_knotrange.c[1] = px->_knot.p[px->_knot.n-1];
2025 fraction = max(px->_knotrange.c[0],px->set_fraction);
2026 fraction = min(px->_knotrange.c[1],px->set_fraction);
2031 float f1, f2, cw1[4], cw2[4], dir[3], rot[4];
2035 f2 = fraction + .01f;
2037 f1 = fraction - .01f;
2041 CurvePoint(px->_xyzw.n, px->order-1, px->_knot.p, (
float*)px->_xyzw.p, f1, cw1 );
2042 CurvePoint(px->_xyzw.n, px->order-1, px->_knot.p, (
float*)px->_xyzw.p, f2, cw2 );
2043 vecdif3f(dir,cw2,cw1);
2044 vecnormalize3f(dir,dir);
2050 float perp[3], dirx[3], sine;
2051 memset(dirx,0,3*
sizeof(
float));
2053 veccross3f(perp,dirx,dir);
2054 sine = veclength3f(perp);
2057 float default_direction [4] = {1.0f, 0.0f, 0.0f, 0.0f};
2058 veccopy4f(rot,default_direction);
2060 float cosine, angle;
2061 vecnormalize3f(perp,perp);
2062 cosine = vecdot3f(dir,dirx);
2063 angle = atan2f(sine,cosine);
2064 veccopy3f(rot,perp);
2071 float perp[3],dir0[3];
2073 CurvePoint(px->_xyzw.n, px->order-1, px->_knot.p, (
float*)px->_xyzw.p, 0.0f, cw1 );
2074 CurvePoint(px->_xyzw.n, px->order-1, px->_knot.p, (
float*)px->_xyzw.p, .001f, cw2 );
2075 vecdif3f(dir0,cw2,cw1);
2076 vecnormalize3f(dir0,dir0);
2078 veccross3f(perp,dir,dir0);
2079 if(veclength3f(perp) == 0.0f){
2081 float default_direction [4] = {1.0f, 0.0f, 0.0f, 0.0f};
2082 veccopy4f(rot,default_direction);
2086 vecnormalize3f(perp,perp);
2087 cosine = vecdot3f(dir0,dir);
2088 angle = acosf(cosine);
2089 veccopy3f(rot,perp);
2093 veccopy4f(px->value_changed.c,rot);
2095 float default_direction [4] = {1.0f, 0.0f, 0.0f, 0.0f};
2096 veccopy4f(px->value_changed.c,default_direction);
2101 printf(
"do_NurbsOrientInt: set_fraction %f value_changed %f %f %f %f\n",fraction,
2102 px->value_changed.c[0],px->value_changed.c[1],px->value_changed.c[2],px->value_changed.c[3] );
2107 void do_NurbsSurfaceInterpolator (
void *_node) {
2108 float uv[2], xyzw[4];
2114 if(node->_nodeType != NODE_NurbsSurfaceInterpolator)
return;
2118 if(node->_OK != TRUE){
2119 int i,j, n, nu, nv, nku, nkv;
2120 GLfloat *xyzw, *knotsu, *knotsv;
2122 nku = nkv = nu = nv = n = 0;
2123 xyzw = knotsu = knotsv = NULL;
2124 if(node->controlPoint){
2125 if(node->controlPoint->_nodeType == NODE_CoordinateDouble){
2129 xyzw = MALLOC(
void *, n * 4 *
sizeof(GLfloat));
2130 for(i=0;i<mfd->n;i++){
2132 xyzw[i*4 + j] = (float)mfd->p[i].c[j];
2135 }
else if(node->controlPoint->_nodeType == NODE_Coordinate){
2139 xyzw = MALLOC(
void *, n * 4 *
sizeof(GLfloat));
2140 for(i=0;i<mff->n;i++){
2142 xyzw[i*4 + j] = mff->p[i].c[j];
2150 if(node->weight.n && node->weight.n == n){
2153 m = min(node->weight.n, n);
2155 im = i < m ? i : m-1;
2156 w = node->weight.p[im];
2157 xyzw[i*4 + 3] = (float)w;
2160 for(i=0;i<n;i++) xyzw[i*4 + 3] = 1.0;
2162 nu = node->uDimension;
2163 nv = node->vDimension;
2164 if(nu * nv != n)
return;
2165 if(nu < node->uOrder)
return;
2166 if(nv < node->vOrder)
return;
2169 if(knotsOK(node->uOrder,nu,node->uKnot.n,node->uKnot.p)){
2172 nku = node->uKnot.n;
2173 knotsu = MALLOC(
void *, nku *
sizeof(GLfloat));
2175 knotsu[i] = (GLfloat)node->uKnot.p[i];
2179 printf(
"good u knot vector nk=%d\n",nku);
2180 for(ii=0;ii<nku;ii++)
2181 printf(
"[%d]=%f \n",ii,knotsu[ii]);
2186 static int once = 0;
2187 nku = nu + node->uOrder ;
2189 knotsu = MALLOC(
void *, nku *
sizeof(GLfloat));
2190 generateUniformKnotVector(node->uOrder,nu, knotsu);
2193 printf(
"bad u knot vector given, replacing with:\n");
2194 for(ii=0;ii<nku;ii++)
2195 printf(
"[%d]=%f \n",ii,knotsu[ii]);
2201 if(knotsOK(node->vOrder,nv,node->vKnot.n,node->vKnot.p)){
2203 nkv = node->vKnot.n;
2204 knotsv = MALLOC(
void *, nkv *
sizeof(GLfloat));
2206 knotsv[i] = (GLfloat)node->vKnot.p[i];
2210 printf(
"good v knot vector nk=%d\n",nkv);
2211 for(ii=0;ii<nkv;ii++)
2212 printf(
"[%d]=%f \n",ii,knotsv[ii]);
2216 static int once = 0;
2218 nkv = nv + node->vOrder ;
2220 knotsv = MALLOC(
void *, nkv *
sizeof(GLfloat));
2221 generateUniformKnotVector(node->vOrder,nv, knotsv);
2224 printf(
"bad v knot vector given, replacing with:\n");
2225 for(ii=0;ii<nkv;ii++)
2226 printf(
"[%d]=%f \n",ii,knotsv[ii]);
2231 node->_controlPoint.p = (
struct SFVec4f*)xyzw;
2232 node->_controlPoint.n = n;
2233 node->_uKnot.p = knotsu;
2234 node->_uKnot.n = nku;
2235 node->_vKnot.p = knotsv;
2236 node->_vKnot.n = nkv;
2242 if(!node->_OK)
return;
2244 veccopy2f(uv,node->set_fraction.c);
2246 ok = SurfacePoint(node->uDimension,node->uOrder-1,node->_uKnot.p,
2247 node->vDimension,node->vOrder-1,node->_vKnot.p,
2248 (
float *)node->_controlPoint.p,uv[1],uv[0],xyzw);
2250 veccopy3f(node->position_changed.c,xyzw);
2254 float udir[3], vdir[3], normal[3], xyz1[4];
2255 ok = SurfacePoint(node->uDimension,node->uOrder-1,node->_uKnot.p,
2256 node->vDimension,node->vOrder-1,node->_vKnot.p,
2257 (
float *)node->_controlPoint.p,uv[1],uv[0]+.01f,xyz1);
2258 vecdif3f(udir,xyz1,xyzw);
2259 ok = SurfacePoint(node->uDimension,node->uOrder-1,node->_uKnot.p,
2260 node->vDimension,node->vOrder-1,node->_vKnot.p,
2261 (
float *)node->_controlPoint.p,uv[1]+.01f,uv[0],xyz1);
2262 vecdif3f(vdir,xyz1,xyzw);
2263 veccross3f(normal,udir,vdir);
2264 vecnormalize3f(normal,normal);
2265 veccopy3f(node->normal_changed.c,normal);
2274 printf (
"Pos/Col, new value (%f %f %f)\n",
2275 px->value_changed.c[0],px->value_changed.c[1],px->value_changed.c[2]);
2287 int nt, np,ic,j,i,k;
2288 double *xyzp, *xyzt;
2299 controlPoint = (
struct X3D_Coordinate*)createNewX3DNode(NODE_Coordinate);
2300 node->_patch = X3D_NODE(patch);
2301 patch->controlPoint = X3D_NODE(controlPoint);
2307 nt = trajectoryxz->controlPoint.n;
2308 np = profileyz->controlPoint.n;
2309 xyzp = (
double*)profileyz->controlPoint.p;
2310 xyzt = (
double*)trajectoryxz->controlPoint.p;
2311 xyz = MALLOC(
float*,nt * np * 3 *
sizeof(
float));
2312 controlPoint->point.p = (
struct SFVec3f*)xyz;
2313 controlPoint->point.n = nt * np;
2317 double2float(pt,&xyzt[j*2],2);
2320 float cosine, sine, swingangle;
2321 double2float(pp,&xyzp[2*i],2);
2322 swingangle = atan2f(pt[1],pt[0]);
2323 cosine = cosf(swingangle);
2324 sine = sinf(swingangle);
2325 xyz[ic*3 + 0] = pt[0] + cosine * pp[0];
2326 xyz[ic*3 + 1] = pp[1];
2327 xyz[ic*3 + 2] = pt[1] + sine * pp[0];
2331 patch->solid = node->solid;
2333 patch->uDimension = np;
2334 patch->uKnot.p = malloc(profileyz->knot.n *
sizeof(
double));
2335 memcpy(patch->uKnot.p,profileyz->knot.p,profileyz->knot.n *
sizeof(
double));
2336 patch->uKnot.n = profileyz->knot.n;
2337 patch->uOrder = profileyz->order;
2338 patch->uTessellation = (int)((
float)profileyz->tessellation * profileyz->_tscale);
2340 patch->vDimension = nt;
2341 patch->vKnot.p = malloc(trajectoryxz->knot.n *
sizeof(
double));
2342 memcpy(patch->vKnot.p,trajectoryxz->knot.p,trajectoryxz->knot.n *
sizeof(
double));
2343 patch->vKnot.n = trajectoryxz->knot.n;
2344 patch->vOrder = trajectoryxz->order;
2345 patch->vTessellation = (int)((
float)trajectoryxz->tessellation * profileyz->_tscale);
2350 printf(
"%f %f %f,",xyz[ic*3 + 0], xyz[ic*3 +1], xyz[ic*3 +2]);
2355 printf(
"uDimension=%d vDimension=%d nc=%d\n",np,nt,ic);
2361 if (!node->_intern)
return;
2362 render_ray_polyrep(node->_patch);
2367 if (!node->_intern)
return;
2368 collide_genericfaceset(node->_patch);
2374 if (!node->_patch->_intern)
2377 CULL_FACE(patch->solid)
2378 render_polyrep(X3D_NODE(patch));
2383 int compute_tessellation(
int tessellation,
int order,
int ncontrol ){
2390 ntessu = tessellation;
2393 mtessu = max(mtessu,ntessu+1);
2395 mtessu = max(mtessu,(-ntessu * ncontrol) + 1);
2397 mtessu = max(mtessu,2*ncontrol + 1);
2400 void compute_knotvector(
int order,
int ncontrol,
int nknots,
double *knots,
int *newnknots,
float **newknots,
float *range){
2406 if(knotsOK(order,ncontrol,nknots,knots)){
2410 knotsu = MALLOC(
void *, nku *
sizeof(GLfloat));
2412 knotsu[i] = (GLfloat)knots[i];
2415 printf(
"good u knot vector nk=%d\n",nku);
2416 for(ii=0;ii<nku;ii++)
2417 printf(
"[%d]=%f \n",ii,knotsu[ii]);
2423 static int once = 0;
2424 nku = ncontrol + order ;
2426 knotsu = MALLOC(
void *, nku *
sizeof(GLfloat));
2427 generateUniformKnotVector(order,ncontrol, knotsu);
2429 printf(
"bad u knot vector given, replacing with:\n");
2430 for(ii=0;ii<nku;ii++)
2431 printf(
"[%d]=%f \n",ii,knotsu[ii]);
2438 range[0] = knotsu[0];
2439 range[1] = knotsu[nku-1];
2441 void compute_weightedcontrol(
double *xyz,
int dim,
int nc,
int nweight,
double *weights,
float **cxyzw){
2451 xyzw = MALLOC(
float *, nc * 4 *
sizeof(GLfloat));
2453 xyzw[i*4 +0] = xyzw[i*4 +1] =xyzw[i*4 +2] =xyzw[i*4 +3] = 0.0f;
2456 xyzw[i*4 + j] = (float)xyz[i*dim + j];
2458 xyzw[i*4 + 3] = 1.0f;
2460 if(nweight && nweight == nc ){
2462 float wt = (float)weights[i];
2464 vecscale3f(&xyzw[i*4],&xyzw[i*4],wt);
2469 void compute_doublecontrol(
struct X3D_Node *controlPoint,
int *nc,
double** xyz ){
2474 double *xyzd = NULL;
2476 switch(controlPoint->_nodeType){
2477 case NODE_Coordinate:
2480 n = tcoord->point.n;
2481 xyzd = MALLOC(
double *,n * 3 *
sizeof(
double));
2482 for(i=0;i<tcoord->point.n;i++)
2483 float2double(&xyzd[i*3],tcoord->point.p[i].c,3);
2486 case NODE_CoordinateDouble:
2489 n = tcoord->point.n;
2490 xyzd = MALLOC(
double *,n * 3 *
sizeof(
double));
2491 for(i=0;i<tcoord->point.n;i++)
2492 veccopyd(&xyzd[i*3],tcoord->point.p[i].c);
2503 float *vecabs3f(
float *res,
float *p){
2506 res[i] = fabsf(p[i]);
2509 int ivecdominantdirection3f(
int *irank,
float *p){
2510 float rmax, rmin, vabs[3];
2513 rmax = max(vabs[0],max(vabs[1],vabs[2]));
2514 rmin = min(vabs[0],min(vabs[1],vabs[2]));
2517 if(vabs[i] == rmax) {
2521 if(vabs[i] == rmin) irank[i] = 0;
2525 void convert_mesh_to_polyrep(
float *xyz,
int npts,
float *nxyz,
int* tindex,
int ntri,
struct X3D_Node *node){
2537 polyrep = node->_intern;
2538 FREE_IF_NZ(polyrep->cindex);
2539 FREE_IF_NZ(polyrep->actualCoord);
2540 FREE_IF_NZ(polyrep->GeneratedTexCoords[0]);
2541 FREE_IF_NZ(polyrep->colindex);
2542 FREE_IF_NZ(polyrep->color);
2543 FREE_IF_NZ(polyrep->norindex);
2544 FREE_IF_NZ(polyrep->normal);
2545 FREE_IF_NZ(polyrep->flat_normal);
2546 FREE_IF_NZ(polyrep->tcindex);
2549 node->_intern = create_polyrep();
2551 rep_ = polyrep = node->_intern;
2564 rep_->actualCoord = xyz;
2565 rep_->normal = nxyz;
2571 rep_->cindex = tindex;
2572 norindex = rep_->norindex = MALLOC(GLuint *,
sizeof(GLuint)*3*ntri);
2573 memcpy(norindex,tindex,
sizeof(GLuint)*3*ntri);
2580 if (polyrep->ntri != 0) {
2582 stream_polyrep(node, NULL,NULL,NULL,NULL, NULL);
2586 polyrep->irep_change = node->_change;
2643 compute_doublecontrol(trajectory->controlPoint,&nt,&xyzt);
2646 np = xsection->controlPoint.n;
2647 xyzx = (
double*)xsection->controlPoint.p;
2679 if(!strcmp(node->method->strptr,
"FULL"))
2681 if(!strcmp(node->method->strptr,
"TRANSLATE"))
2683 if(node->_method == 1){
2695 controlPoint = (
struct X3D_Coordinate*) createNewX3DNode(NODE_Coordinate);
2696 node->_patch = X3D_NODE(patch);
2697 patch->controlPoint = X3D_NODE(controlPoint);
2699 xyz = MALLOC(
float*,nt * np * 3 *
sizeof(
float));
2700 controlPoint->point.p = (
struct SFVec3f*) xyz;
2701 controlPoint->point.n = nt * np;
2706 double2float(pt,&xyzt[j*3],3);
2709 double2float(pp,&xyzx[2*i],2);
2710 xyz[ic*3 + 0] = pt[0] + pp[0];
2711 xyz[ic*3 + 1] = pt[1] + pp[1];
2712 xyz[ic*3 + 2] = pt[2];
2718 if((trajectory->weight.n && trajectory->weight.n == nt) ||
2719 (xsection->weight.n && xsection->weight.n == np)){
2722 weight = MALLOC(
double*,nt * np *
sizeof(
double));
2724 double wtTj = trajectory->weight.p[j];
2726 weight[j*np + i] = wtTj * xsection->weight.p[i];
2732 patch->weight.p = weight;
2733 patch->weight.n = nt * np;
2735 patch->solid = node->solid;
2737 patch->uDimension = np;
2738 patch->uKnot.p = malloc(xsection->knot.n *
sizeof(
double));
2739 memcpy(patch->uKnot.p,xsection->knot.p,xsection->knot.n *
sizeof(
double));
2740 patch->uKnot.n = xsection->knot.n;
2741 patch->uOrder = xsection->order;
2742 patch->uTessellation = (int)((
float)xsection->tessellation * xsection->_tscale);
2744 patch->vDimension = nt;
2745 patch->vKnot.p = malloc(xsection->knot.n *
sizeof(
double));
2746 memcpy(patch->vKnot.p,trajectory->knot.p,trajectory->knot.n *
sizeof(
double));
2747 patch->vKnot.n = trajectory->knot.n;
2748 patch->vOrder = trajectory->order;
2749 patch->vTessellation = (int)((
float)trajectory->tessellation * trajectory->_tscale);
2754 printf(
"%f %f %f,",xyz[ic*3 + 0], xyz[ic*3 +1], xyz[ic*3 +2]);
2759 printf(
"uDimension=%d vDimension=%d nc=%d\n",np,nt,ic);
2763 if(node->_method == 2){
2765 int mtessv, mtessu, nku, nkv;
2767 float *knotsu,*knotsv,*xyzwu,*xyzwv, urange[2],vrange[2];
2768 float *Tv, *Tangentv, *Bup, *pts;
2777 int mtessu1, mtessv1;
2779 mtessu = compute_tessellation(xsection->tessellation,xsection->order,np);
2780 mtessu = (int)((
float)mtessu * xsection->_tscale);
2781 mtessv = compute_tessellation(trajectory->tessellation,trajectory->order,nt);
2782 mtessv = (int)((
float)mtessv * trajectory->_tscale);
2783 compute_knotvector(xsection->order,np,xsection->knot.n,xsection->knot.p,&nku,&knotsu,urange);
2784 compute_knotvector(trajectory->order,nt,trajectory->knot.n,trajectory->knot.p,&nkv,&knotsv,vrange);
2785 compute_weightedcontrol(xyzt,3,nt, trajectory->weight.n, trajectory->weight.p, &xyzwv);
2786 compute_weightedcontrol(xyzx,2,np, xsection->weight.n, xsection->weight.p, &xyzwu);
2790 printf(
"np %d mtessu %d nku %d, nt %d mtessv %d, nkv %d",np,mtessu,nku,nt,mtessv,nkv);
2791 printf(
"trajectory nt %d points:\n",nt);
2793 printf(
"%d %f %f %f %f\n",i,xyzwv[i*4 + 0],xyzwv[i*4 + 1],xyzwv[i*4 + 2],xyzwv[i*4 + 3]);
2794 printf(
"xsection np %d points:\n",np);
2796 printf(
"%d %f %f %f %f\n",i,xyzwu[i*4 + 0],xyzwu[i*4 + 1],xyzwu[i*4 + 2],xyzwu[i*4 + 3]);
2806 mtessu1 = mtessu + 1;
2807 mtessv1 = mtessv + 1;
2808 Tv = MALLOC(
float*,(mtessv1)*3*
sizeof(
float));
2809 Tangentv = MALLOC(
float*,(mtessv1)*3*
sizeof(
float));
2810 Bup = MALLOC(
float*,(mtessv1)*3*
sizeof(
float));
2811 for(i=0;i<mtessv1;i++){
2812 float cw[4], cw1[4], delta[3], v;
2813 v = (float)i*(vrange[1]-vrange[0])/(float)mtessv;
2814 CurvePoint(nt, trajectory->order-1, knotsv, xyzwv, v, cw );
2815 veccopy3f(&Tv[i*3],cw);
2817 CurvePoint(nt, trajectory->order-1, knotsv, xyzwv, v+.01f, cw1 );
2818 vecdif3f(delta,cw1,cw);
2820 vecnormalize3f(delta,delta);
2821 veccopy3f(&Tangentv[i*3],delta);
2825 int k,irank[3],idom, inondom;
2826 float perp[3], perp2[3];
2827 idom = ivecdominantdirection3f(irank,delta);
2828 inondom = idom + 1 > 2 ? 0 : idom + 1;
2829 for(k=0;k<3;k++)
if(irank[k] == 0) inondom = k;
2830 memset(perp,0,3*
sizeof(
float));
2831 perp[inondom] = 1.0;
2832 veccross3f(perp2,delta,perp);
2833 veccross3f(perp,perp2,delta);
2835 veccopy3f(&Bup[i*3],perp);
2839 float bi[3], bi1dotti, tiscaled[3];
2840 bi1dotti = vecdot3f(&Bup[(i-1)*3],&Tangentv[i*3]);
2841 vecdif3f(bi,&Bup[(i-1)*3],vecscale3f(tiscaled,&Tangentv[i*3],bi1dotti));
2842 vecnormalize3f(&Bup[i*3],bi);
2846 printf(
"trajectory T:\n");
2847 for(i=0;i<mtessv1;i++){
2848 printf(
"%d [%f %f %f] \n",i,
2849 Tv[i*3 +0],Tv[i*3 +1],Tv[i*3 +2]);
2851 printf(
"trajectory T', B:\n");
2852 for(i=0;i<mtessv1;i++){
2853 printf(
"%d [%f %f %f] [%f %f %f] \n",i,
2854 Tangentv[i*3 +0],Tangentv[i*3 +1],Tangentv[i*3 +2],
2855 Bup[i*3 +0],Bup[i*3 +1],Bup[i*3 +2]);
2863 Qu = MALLOC(
float*,(mtessu+1)*3*
sizeof(
float));
2864 Nu = MALLOC(
float*,(mtessu+1)*3*
sizeof(
float));
2865 if(DBGSW) printf(
"Xsection tess pts:\n");
2866 for(i=0;i<mtessu1;i++){
2867 float u, cw[4], cw1[4], delta[3], normal[3];
2868 float zzz[3] = {0.0f,0.0f,1.0f};
2869 u = (float)i*(urange[1]-urange[0])/(float)mtessu;
2870 CurvePoint(np, xsection->order-1, knotsu, xyzwu, u, cw );
2871 veccopy3f(&Qu[i*3],cw);
2872 CurvePoint(np, xsection->order-1, knotsu, xyzwu, u+.01f, cw1 );
2873 vecdif3f(delta,cw1,cw);
2874 vecnormalize3f(delta,delta);
2875 veccross3f(normal,zzz,delta);
2876 veccopy3f(&Nu[i*3],normal);
2877 if(DBGSW) printf(
"%d %f %f %f\n",i,Qu[i*3 +0],Qu[i*3 +1],Qu[i*3 +2]);
2883 pts = MALLOC(
float*,mtessu1 * mtessv1 * 3 *
sizeof(
float));
2884 normals = MALLOC(
float*,mtessu1 * mtessv1 * 3 *
sizeof(
float));
2885 idx = MALLOC(
int *, mtessu * mtessv * 2 * 3 *
sizeof(
int));
2888 for(i=0;i<mtessv1;i++){
2890 float mat [9], matt[9];
2895 veccross3f(&mat[0],&Bup[i*3],&Tangentv[i*3]);
2896 veccopy3f(&mat[3],&Bup[i*3]);
2897 veccopy3f(&mat[6],&Tangentv[i*3]);
2898 mattranspose3f(matt,mat);
2906 memcpy(matB0,mat,9*
sizeof(
float));
2908 matmultiply3f(mat,matt,matB0);
2909 for(j=0;j<mtessu1;j++){
2910 float pp[3], norm[3];
2911 matmultvec3f(pp, mat, &Qu[j*3] );
2912 vecadd3f(pp,pp,&Tv[i*3]);
2913 veccopy3f(&pts[ic*3],pp);
2914 matmultvec3f(norm,mat,&Nu[j*3]);
2915 veccopy3f(&normals[ic*3],norm);
2923 for(j=0;j<mtessu;j++){
2940 printf(
"ntri %d triangle indexes:\n",ntri);
2941 for(i=0;i<ntri;i++){
2945 printf(
"%d ",idx[i*3 +j]);
2949 printf(
"triangle vertices:\n");
2950 for(i=0;i<ntri;i++){
2954 int ix = idx[i*3 +j];
2955 veccopy3f(pt,&pts[ix*3]);
2956 printf(
"%d %d %f %f %f\n",i,ix,pt[0],pt[1],pt[2]);
2962 convert_mesh_to_polyrep(pts,ic,normals,idx,ntri,X3D_NODE(node));
2968 if(node->_method == 1){
2969 if (!node->_patch)
return;
2970 render_ray_polyrep(node->_patch);
2972 if(node->_method == 2){
2973 if(!node->_intern)
return;
2974 render_ray_polyrep(node);
2980 if(node->_method == 1){
2981 if (!node->_patch)
return;
2982 collide_genericfaceset(node->_patch);
2984 if(node->_method == 2){
2985 if (!node->_intern)
return;
2986 collide_genericfaceset(node);
2992 if(node->_method == 1){
2994 if (!node->_patch->_intern)
2997 CULL_FACE(patch->solid)
2998 render_polyrep(patch);
3000 if(node->_method == 2){
3004 render_polyrep(node);
3012 for(i=0;i<node->geometry.n;i++){
3014 switch(gn->_nodeType){
3015 case NODE_NurbsCurve:
3018 g->_tscale = node->tessellationScale;
3022 case NODE_NurbsCurve2D:
3025 g->_tscale = node->tessellationScale;
3029 case NODE_NurbsPatchSurface:
3032 g->_tscale = node->tessellationScale;
3036 case NODE_NurbsTrimmedSurface:
3039 g->_tscale = node->tessellationScale;
3043 case NODE_NurbsSweptSurface:
3046 if(g->_method == 1){
3049 patch->_tscale = node->tessellationScale;
3053 if(g->_method == 2){
3055 curve->_tscale = node->tessellationScale;
3056 MNX(g->crossSectionCurve);
3058 curve->_tscale = node->tessellationScale;
3059 MNX(g->trajectoryCurve);
3063 case NODE_NurbsSwungSurface:
3068 patch->_tscale = node->tessellationScale;
3091 void do_NurbsPositionInterpolator (
void *node) {}
3092 void do_NurbsOrientationInterpolator (
void *node){}
3093 void do_NurbsSurfaceInterpolator (
void *_node){}