34#include <libFreeWRL.h>
36#include "../vrml_parser/Structs.h"
37#include "../main/headers.h"
38#include "../scenegraph/Component_ProgrammableShaders.h"
42#include "../scenegraph/quaternion.h"
44#include "LinearAlgebra.h"
45#include "../input/SensInterps.h"
46#include "system_threads.h"
49#include "../opengl/OpenGL_Utils.h"
50#include "../opengl/Textures.h"
51#include "../scenegraph/Component_Shape.h"
52#include "RenderFuncs.h"
53#include "../ui/common.h"
55typedef float shaderVec4[4];
83 void *elements_indices;
89 int profile_entry_count;
108 Stack *render_geom_stack;
111 Stack *shaderflags_stack;
118 Stack *usehits_stack;
119 Stack *usehitsB_stack;
120 Stack *pickablegroupdata_stack;
121 Stack *draw_call_params_stack;
123void *RenderFuncs_constructor(){
128void RenderFuncs_init(
struct tRenderFuncs *t){
131 t->BrowserAction = FALSE;
136 t->hypersensitive = 0;
138 t->have_transparency=FALSE;
141 t->last_texture_type = NOTEXTURE;
144 t->prv = RenderFuncs_constructor();
146 ppRenderFuncs p = (ppRenderFuncs)t->prv;
147 p->profile_entry_count = 0;
152 p->libraries=newVector(
void3 *,1);
153 p->AnchorsAnchor = NULL;
154 t->rayHit = (
void *)&p->rayHit;
161 p->render_geom_stack = newStack(
int);
162 p->sensor_stack = newStack(
struct currayhit);
164 p->usehits_stack = newStack(
usehit);
165 p->usehitsB_stack = newStack(
usehit);
166 p->pickablegroupdata_stack = newStack(
void*);
168 p->fog_stack = newStack(
struct X3D_Node*);
169 p->ectx_stack = newStack(
struct X3D_Node*);
172 t->hp = (
void *)&p->hp;
182void usehit_add(
struct X3D_Node * node,
double *modelviewmatrix){
185 ppRenderFuncs p = (ppRenderFuncs)gglobal()->RenderFuncs.prv;
187 memcpy(uhit.mvm,modelviewmatrix,16*
sizeof(
double));
188 uhit.userdata = NULL;
189 vector_pushBack(
usehit,p->usehits_stack,uhit);
191void usehit_add2(
struct X3D_Node * node,
double *modelviewmatrix,
void *userdata){
194 ppRenderFuncs p = (ppRenderFuncs)gglobal()->RenderFuncs.prv;
196 memcpy(uhit.mvm,modelviewmatrix,16*
sizeof(
double));
197 uhit.userdata = userdata;
198 vector_pushBack(
usehit,p->usehits_stack,uhit);
205 ppRenderFuncs p = (ppRenderFuncs)gglobal()->RenderFuncs.prv;
207 if(vectorSize(p->usehits_stack)>0){
218 istart = ((
char*)lasthit - (
char*)vector_get_ptr(
usehit,p->usehits_stack,0))/
sizeof(
usehit) + 1;
221 for(i=istart;i<p->usehits_stack->n;i++){
222 item = vector_get_ptr(
usehit,p->usehits_stack,i);
223 if(item->node == node){
234 ppRenderFuncs p = (ppRenderFuncs)gglobal()->RenderFuncs.prv;
235 p->usehits_stack->n = 0;
241void usehitB_add(
struct X3D_Node * node,
double *modelviewmatrix){
244 ppRenderFuncs p = (ppRenderFuncs)gglobal()->RenderFuncs.prv;
246 memcpy(uhit.mvm,modelviewmatrix,16*
sizeof(
double));
247 uhit.userdata = NULL;
248 vector_pushBack(
usehit,p->usehitsB_stack,uhit);
250void usehitB_add2(
struct X3D_Node * node,
double *modelviewmatrix,
void *userdata){
253 ppRenderFuncs p = (ppRenderFuncs)gglobal()->RenderFuncs.prv;
255 memcpy(uhit.mvm,modelviewmatrix,16*
sizeof(
double));
256 uhit.userdata = userdata;
257 vector_pushBack(
usehit,p->usehitsB_stack,uhit);
264 ppRenderFuncs p = (ppRenderFuncs)gglobal()->RenderFuncs.prv;
266 if(vectorSize(p->usehitsB_stack)>0){
277 istart = ((
char*)lasthit - (
char*)vector_get_ptr(
usehit,p->usehitsB_stack,0))/
sizeof(
usehit) + 1;
280 for(i=istart;i<p->usehitsB_stack->n;i++){
281 item = vector_get_ptr(
usehit,p->usehitsB_stack,i);
282 if(item->node == node){
293 ppRenderFuncs p = (ppRenderFuncs)gglobal()->RenderFuncs.prv;
294 p->usehitsB_stack->n = 0;
296Stack *getUseHitBStack(){
297 ppRenderFuncs p = (ppRenderFuncs)gglobal()->RenderFuncs.prv;
298 return p->usehitsB_stack;
304void push_pickablegroupdata(
void *userdata){
305 ppRenderFuncs p = (ppRenderFuncs)gglobal()->RenderFuncs.prv;
306 stack_push(
void*,p->pickablegroupdata_stack,userdata);
308void pop_pickablegroupdata(){
309 ppRenderFuncs p = (ppRenderFuncs)gglobal()->RenderFuncs.prv;
310 stack_pop(
void*,p->pickablegroupdata_stack);
312void *getpickablegroupdata(){
314 ppRenderFuncs p = (ppRenderFuncs)gglobal()->RenderFuncs.prv;
316 if(vectorSize(p->pickablegroupdata_stack)>0)
317 ret = stack_top(
void*,p->pickablegroupdata_stack);
322void unload_libraryscenes();
323int gc_broto_instance(
struct X3D_Proto* node);
324void RenderFuncs_clear(
struct tRenderFuncs *t){
325 ppRenderFuncs p = (ppRenderFuncs)t->prv;
326 unload_libraryscenes();
327 deleteVector(
void3 *,p->libraries);
328 deleteVector(
int,p->render_geom_stack);
329 deleteVector(
struct currayhit,p->sensor_stack);
331 deleteVector(
usehit,p->usehits_stack);
334 deleteVector(
struct X3D_Node*,p->fog_stack);
337void unload_libraryscenes(){
338 ppRenderFuncs p = (ppRenderFuncs)gglobal()->RenderFuncs.prv;
347 for(i=0;i<vectorSize(p->libraries);i++){
351 ul = vector_get(
struct void3*,p->libraries,i);
353 url = (
char *)ul->one;
356 gc_broto_instance(libscn);
357 deleteVector(
struct X3D_Node*,libscn->_parentVector);
358 freeMallocedNodeFields((
struct X3D_Node*)libscn);
363 vector_set(
struct void3*,p->libraries,i,NULL);
370void transformPositionToEye(
float *pos)
373 GLDOUBLE modelMatrix[16], *b;
376 FW_GL_GETDOUBLEV(GL_MODELVIEW_MATRIX, modelMatrix);
384 transformf(aux,pos,modelMatrix);
391void transformDirectionToEye(
float *dir)
394 GLDOUBLE modelMatrix[16], *b;
397 FW_GL_GETDOUBLEV(GL_MODELVIEW_MATRIX, modelMatrix);
401 aux[0] = (float) (b[0]*a[0] +b[4]*a[1] +b[8]*a[2] );
402 aux[1] = (float) (b[1]*a[0] +b[5]*a[1] +b[9]*a[2] );
403 aux[2] = (float) (b[2]*a[0] +b[6]*a[1] +b[10]*a[2]);
408void transformLightToEye(
float *pos,
float* dir)
411 GLDOUBLE modelMatrix[16], *b;
413 shaderVec4 aux, auxt;
414 FW_GL_GETDOUBLEV(GL_MODELVIEW_MATRIX, modelMatrix);
429 transformf(auxt,pos,modelMatrix);
443 aux[0] = (float) (b[0]*a[0] +b[4]*a[1] +b[8]*a[2] );
444 aux[1] = (float) (b[1]*a[0] +b[5]*a[1] +b[9]*a[2] );
445 aux[2] = (float) (b[2]*a[0] +b[6]*a[1] +b[10]*a[2]);
456void finishedWithGlobalShader(
void) {
461 getAppearanceProperties()->currentShaderProperties = NULL;
462FW_GL_BINDBUFFER(GL_ARRAY_BUFFER, 0);
464FW_GL_BINDBUFFER(GL_ELEMENT_ARRAY_BUFFER, 0);
473void resetGlobalShader() {
474 ppRenderFuncs p = (ppRenderFuncs)gglobal()->RenderFuncs.prv;
479 p->currentShader = 0;
482void restoreGlobalShader(){
483 ppRenderFuncs p = (ppRenderFuncs)gglobal()->RenderFuncs.prv;
484 if (p->currentShader)
485 USE_SHADER(p->currentShader);
489void enableGlobalShader(s_shader_capabilities_t *myShader) {
490 ppRenderFuncs p = (ppRenderFuncs)gglobal()->RenderFuncs.prv;
493 if (myShader == NULL) {
494 finishedWithGlobalShader();
499 getAppearanceProperties()->currentShaderProperties = myShader;
500 if (myShader->myShaderProgram != p->currentShader) {
501 USE_SHADER(myShader->myShaderProgram);
502 p->currentShader = myShader->myShaderProgram;
508void sendAttribToGPU(
int myType,
int dataSize,
int dataType,
int normalized,
int stride,
void *pointer,
int texID,
char *file,
int line){
510 s_shader_capabilities_t *me = getAppearanceProperties()->currentShaderProperties;
518ConsoleMessage (
"sendAttribToGPU, getAppearanceProperties()->currentShaderProperties %p\n",getAppearanceProperties()->currentShaderProperties);
519ConsoleMessage (
"myType %d, dataSize %d, dataType %d, stride %d\n",myType,dataSize,dataType,stride);
522 case FW_NORMAL_POINTER_TYPE:
523 ConsoleMessage (
"glVertexAttribPointer Normals %d at %s:%d\n",me->Normals,file,line);
525 case FW_VERTEX_POINTER_TYPE:
526 ConsoleMessage (
"glVertexAttribPointer Vertexs %d at %s:%d\n",me->Vertices,file,line);
528 case FW_COLOR_POINTER_TYPE:
529 ConsoleMessage (
"glVertexAttribPointer Colours %d at %s:%d\n",me->Colours,file,line);
531 case FW_TEXCOORD_POINTER_TYPE:
532 ConsoleMessage (
"glVertexAttribPointer TexCoords %d at %s:%d\n",me->TexCoords,file,line);
535 default : {ConsoleMessage (
"sendAttribToGPU, unknown type in shader\n");}
542 case FW_NORMAL_POINTER_TYPE:
543 if (me->Normals != -1) {
544 glEnableVertexAttribArray(me->Normals);
545 glVertexAttribPointer(me->Normals, 3, dataType, normalized, stride, pointer);
548 case FW_FOG_POINTER_TYPE:
549 if (me->FogCoords != -1) {
550 glEnableVertexAttribArray(me->FogCoords);
551 glVertexAttribPointer(me->FogCoords, 1, dataType, normalized, stride, pointer);
555 case FW_VERTEX_POINTER_TYPE:
556 if (me->Vertices != -1) {
557 glEnableVertexAttribArray(me->Vertices);
558 glVertexAttribPointer(me->Vertices, dataSize, dataType, normalized, stride, pointer);
561 case FW_COLOR_POINTER_TYPE:
562 if (me->Colours != -1) {
563 glEnableVertexAttribArray(me->Colours);
564 glVertexAttribPointer(me->Colours, dataSize, dataType, normalized, stride, pointer);
567 case FW_TEXCOORD_POINTER_TYPE:
568 if (me->TexCoords[texID] != -1) {
569 glEnableVertexAttribArray(me->TexCoords[texID]);
570 glVertexAttribPointer(me->TexCoords[texID], dataSize, dataType, normalized, stride, pointer);
574 case FW_CINDEX_POINTER_TYPE:
575 if (me->Cindex != -1) {
578 glEnableVertexAttribArray(me->Cindex);
582 glVertexAttribIPointer(me->Cindex, 1, dataType, stride, pointer);
587 default : {printf (
"sendAttribToGPU, unknown type in shader\n");}
592void sendBindBufferToGPU (GLenum target, GLuint buffer,
char *file,
int line) {
603 glBindBuffer(target,buffer);
610void sendFogToShader(s_shader_capabilities_t *me);
611void sendClipplanesToShader(s_shader_capabilities_t *me);
614 s_shader_capabilities_t *mysp = getAppearanceProperties()->currentShaderProperties;
616PRINT_GL_ERROR_IF_ANY(
"BEGIN setupShader");
621 if (!(mysp->compiledOK)) {
623 printf (
"shader compile error\n");
625 PRINT_GL_ERROR_IF_ANY(
"EXIT(false) setupShader");
630 printf (
"setupShader, we have Normals %d Vertices %d Colours %d TexCoords %d \n",
639 sendFogToShader(mysp);
642 sendClipplanesToShader(mysp);
645 sendMaterialsToShader(mysp);
648 sendMatriciesToShader(mysp);
660void saveArraysForGPU(
int mode,
int first,
int count){
663 ttglobal tg = gglobal();
664 p = (ppRenderFuncs)tg->RenderFuncs.prv;
667 params.arrays.arrays_mode = mode;
668 params.arrays.arrays_count = count;
669 params.arrays.arrays_first = first;
674void saveElementsForGPU0(
int mode,
int count,
int type,
void *indices){
679 ttglobal tg = gglobal();
680 p = (ppRenderFuncs)tg->RenderFuncs.prv;
683 params.elements.elements_count = count;
684 params.elements.elements_mode = mode;
685 params.elements.elements_indices = indices;
686 params.elements.elements_type = type;
692void reallyDrawOnce() {
698 ttglobal tg = gglobal();
699 p = (ppRenderFuncs)tg->RenderFuncs.prv;
700 int loc_side = glGetUniformLocation(p->currentShader,
"material_side");
701 int twosided = getAppearanceProperties()->twosided;
702 int nsides = twosided ? 2 : 1;
703 if (!twosided) glUniform1i(loc_side, 0);
704 for (
int k = 0; k < nsides; k++) {
705 if(twosided) glUniform1i(loc_side, k+1);
706 for (i = 0; i < vectorSize(p->draw_call_params_stack); i++) {
708 if (params->calltype == 1) {
713#define CATCH_GLDRAWARRAYS_THROWS 1
714#if defined(CATCH_GLDRAWARRAYS_THROWS) && defined(_MSC_VER) && defined(W_DEBUG)
716 glDrawArrays(params->arrays.arrays_mode, params->arrays.arrays_first, params->arrays.arrays_count);
718 __except (EXCEPTION_EXECUTE_HANDLER) {
719 printf(
"\n ouch from reallyDrawOnce glDrawArrays \n");
720 printf(
"i= %d n= %d", i, vectorSize(p->draw_call_params_stack));
723 glDrawArrays(params->arrays.arrays_mode, params->arrays.arrays_first, params->arrays.arrays_count);
726 else if (params->calltype == 2) {
727 glDrawElements(params->elements.elements_mode, params->elements.elements_count, params->elements.elements_type, params->elements.elements_indices);
736 ttglobal tg = gglobal();
737 p = (ppRenderFuncs)tg->RenderFuncs.prv;
738 p->draw_call_params_stack->n = 0;
745void sendArraysToGPU (
int mode,
int first,
int count) {
747 printf (
"sendArraysToGPU start\n");
763 profile_start(
"draw_arr");
765 saveArraysForGPU(mode,first,count);
766 profile_end(
"draw_arr");
769 printf (
"sendArraysToGPU end\n");
775void sendElementsToGPU (
int mode,
int count,
int *indices) {
777 printf (
"sendElementsToGPU start\n");
781 profile_start(
"draw_el");
783 saveElementsForGPU0(mode,count,GL_UNSIGNED_INT, indices);
784 profile_end(
"draw_el");
788 printf (
"sendElementsToGPU finish\n");
793ttrenderstate renderstate()
795 ppRenderFuncs p = (ppRenderFuncs)gglobal()->RenderFuncs.prv;
796 return stack_top_ptr(
struct trenderstate,p->renderstate);
798void push_new_renderstate() {
799 ppRenderFuncs p = (ppRenderFuncs)gglobal()->RenderFuncs.prv;
804void pop_renderstate() {
805 ppRenderFuncs p = (ppRenderFuncs)gglobal()->RenderFuncs.prv;
809GLint viewport[4] = {-1,-1,2,2};
816struct point_XYZ r1 = {.x=0,.y=0,.z=-1}, r2 = {.x=0,.y=0,.z=0}, r3 = {.x=0,.y=1,.z=0};
821 ppRenderFuncs p = (ppRenderFuncs)gglobal()->RenderFuncs.prv;
822 return p->AnchorsAnchor;
824void setAnchorsAnchor(
struct X3D_Anchor* anchor)
826 ppRenderFuncs p = (ppRenderFuncs)gglobal()->RenderFuncs.prv;
827 p->AnchorsAnchor = anchor;
841 ppRenderFuncs p = (ppRenderFuncs)gglobal()->RenderFuncs.prv;
843 ConsoleMessage (
"rootNode, p null");
848void setRootNode(
struct X3D_Node *rn)
850 ppRenderFuncs p = (ppRenderFuncs)gglobal()->RenderFuncs.prv;
863void addLibrary(
char *url,
struct X3D_Proto *library,
void *res){
865 ppRenderFuncs p = (ppRenderFuncs)gglobal()->RenderFuncs.prv;
866 ul->one = (
void *)STRDUP(url);
867 ul->two = (
void *)library;
869 vector_pushBack(
void3 *,p->libraries,ul);
871void3 *librarySearch(
char *absoluteUniUrlNoPound){
872 ppRenderFuncs p = (ppRenderFuncs)gglobal()->RenderFuncs.prv;
877 n = vectorSize(libs);
879 ul = vector_get(
void3 *,libs,i);
881 if(!strcmp(absoluteUniUrlNoPound,ul->one)){
894void prepare_model_view_pickmatrix0(GLDOUBLE *modelMatrix, GLDOUBLE *mvp){
897 GLDOUBLE *pickMatrixi;
899 pickMatrixi = getPickrayMatrix(1);
902 matmultiplyAFFINE(mvp,modelMatrix,pickMatrixi);
905void prepare_model_view_pickmatrix_inverse0(GLDOUBLE *modelMatrix, GLDOUBLE *mvpi){
910 GLDOUBLE *pickMatrix;
912 pickMatrix = getPickrayMatrix(0);
915 matinverseAFFINE(mvi,modelMatrix);
916 matmultiplyAFFINE(mvpi,pickMatrix,mvi);
939void rayhit(
float rat,
float cx,
float cy,
float cz,
float nx,
float ny,
float nz,
940 float tx,
float ty,
char *descr) {
941 GLDOUBLE modelMatrix[16];
943 ttglobal tg = gglobal();
944 p = (ppRenderFuncs)tg->RenderFuncs.prv;
955 if(rat<0 || (rat>tg->RenderFuncs.hitPointDist && tg->RenderFuncs.hitPointDist >= 0)) {
958 FW_GL_GETDOUBLEV(GL_MODELVIEW_MATRIX, modelMatrix);
962 tp.x = cx; tp.y = cy; tp.z = cz;
963 prepare_model_view_pickmatrix0(modelMatrix,mvp);
964 transform(&tp,&tp,mvp);
967 tg->RenderFuncs.hitPointDist = rat;
970 printf (
"Rayhit, hp.x y z: - %f %f %f hitPointDist %f %s\n",p->hp.x,p->hp.y,p->hp.z, rat, descr);
981 GLDOUBLE modelMatrix[16];
982 FW_GL_GETDOUBLEV(GL_MODELVIEW_MATRIX, modelMatrix);
995 struct point_XYZ r11 = {.x=0.0,.y=0.0,.z=1.0};
1001 struct point_XYZ view_cam_axis, local_cam_axis;
1003 view_cam_axis.x = 0.0;
1004 view_cam_axis.y = 0.0;
1005 view_cam_axis.z = -1.0;
1006 matinverseAFFINE(mvi,modelMatrix);
1007 transformAFFINE(&local_cam_axis,&view_cam_axis,mvi);
1008 tg->RenderFuncs.camera_axis[0] = local_cam_axis.x;
1009 tg->RenderFuncs.camera_axis[1] = local_cam_axis.y;
1010 tg->RenderFuncs.camera_axis[2] = local_cam_axis.z;
1013 prepare_model_view_pickmatrix_inverse0(modelMatrix, mvpi);
1014 transform(t_r1,&r11,mvpi);
1015 transform(t_r2,&r2,mvpi);
1016 transform(t_r3,&r3,mvpi);
1027void setup_pickray0();
1030 ttglobal tg = gglobal();
1031 p = (ppRenderFuncs)tg->RenderFuncs.prv;
1034 upd_ray0(&p->t_r123.p1,&p->t_r123.p2,&p->t_r123.p3);
1042void transformMBB(GLDOUBLE *rMBBmin, GLDOUBLE *rMBBmax, GLDOUBLE *matTransform, GLDOUBLE* inMBBmin, GLDOUBLE* inMBBmax);
1043int pickrayHitsMBB(
struct X3D_Node *node){
1048 GLDOUBLE modelMatrix[16];
1055 GLDOUBLE smin[3], smax[3], shapeMBBmin[3], shapeMBBmax[3];
1060 FW_GL_GETDOUBLEV(GL_MODELVIEW_MATRIX, modelMatrix);
1062 prepare_model_view_pickmatrix0(modelMatrix, mvp);
1066 shapeMBBmin[i] = node->_extent[i*2 + 1];
1067 shapeMBBmax[i] = node->_extent[i*2];
1069 transformMBB(smin,smax,mvp,shapeMBBmin,shapeMBBmax);
1073 isIn = isIn && (smin[i] <= 0.0 && smax[i] >= 0.0);
1087void update_node(
struct X3D_Node *node) {
1089 static int depth = 0;
1096 printf (
"update_node for %d %s nparents %d renderflags %x\n",node, stringNodeType(node->_nodeType),node->_nparents, node->_renderFlags);
1097 if (node->_nparents == 0) {
1098 if (node == rootNode) printf (
"...no parents, this IS the rootNode\n");
1099 else printf (
"...no parents, this IS NOT the rootNode\n");
1104 for (i = 0; i < node->_nparents; i++) {
1105 struct X3D_Node *n = X3D_NODE(node->_parents[i]);
1107 printf (
" parent %u is %s\n",n,stringNodeType(n->_nodeType));
1109 printf (
" parent %d is NULL\n",i);
1117 if (node->_parentVector == NULL) {
1121 for (i = 0; i < vectorSize(node->_parentVector); i++) {
1124 fprintf(stderr,
"Error: self-referential node structure! (node:'%s')\n", stringNodeType(node->_nodeType));
1125 vector_set(
struct X3D_Node*, node->_parentVector, i,NULL);
1126 }
else if( n != 0 ) {
1145#define PRINT_NODE(_node, _v) do { \
1146 if (gglobal()->internalc.global_print_opengl_errors && (gglobal()->display._global_gl_err != GL_NO_ERROR)) { \
1147 printf("Render_node_v %p (%s) PREP: %p REND: %p CH: %p FIN: %p RAY: %p HYP: %p\n",_v, \
1148 stringNodeType(_node->_nodeType), \
1154 gglobal()->RenderFuncs.hypersensitive); \
1155 printf("Render_state geom %d light %d sens %d\n", \
1156 renderstate()->render_geom, \
1157 renderstate()->render_light, \
1158 renderstate()->render_sensitive); \
1159 printf("pchange %d pichange %d \n", _node->_change, _node->_ichange); \
1176void profile_start(
char *name){
1180 ttglobal tg = gglobal();
1181 p = (ppRenderFuncs)tg->RenderFuncs.prv;
1183 if (!p->profiling_on)
return;
1184 pe = p->profile_entries;
1186 for(i=0;i<p->profile_entry_count;i++){
1187 if(!strcmp(name,pe[i].name)){
1193 pe[p->profile_entry_count].name = name;
1194 pe[p->profile_entry_count].hits = 0;
1195 ifound = p->profile_entry_count;
1196 p->profile_entry_count++;
1198 pe[ifound].start = Time1970sec();
1200void profile_end(
char *name){
1204 ttglobal tg = gglobal();
1205 p = (ppRenderFuncs)tg->RenderFuncs.prv;
1207 if (!p->profiling_on)
return;
1208 pe = p->profile_entries;
1209 for(i=0;i<p->profile_entry_count;i++){
1210 if(!strcmp(name,pe[i].name)){
1216 pe[ifound].accum += Time1970sec() - pe[ifound].start;
1220void profile_print_all(){
1224 ttglobal tg = gglobal();
1225 p = (ppRenderFuncs)tg->RenderFuncs.prv;
1226 if (!p->profiling_on){
1227 p->profiling_on = 1;
1228 ConsoleMessage(
"turning profiling on\n");
1231 pe = p->profile_entries;
1232 ConsoleMessage(
"frame rate: %9.3f number of items tracked: %d\n", gglobal()->Mainloop.BrowserFPS,p->profile_entry_count);
1233 ConsoleMessage(
"%15s %10s %15s %10s\n",
"profile name",
"hits",
"time(sec)",
"% of 1st");
1234 for (i = 0; i < p->profile_entry_count; i++){
1235 ConsoleMessage(
"%15s %10d %15.3f %10.2f\n", pe[i].name, pe[i].hits, pe[i].accum, pe[i].accum / pe[0].accum*100.0);
1246 ttglobal tg = gglobal();
1247 ppRenderFuncs p = (ppRenderFuncs)tg->RenderFuncs.prv;
1259 ttglobal tg = gglobal();
1260 ppRenderFuncs p = (ppRenderFuncs)tg->RenderFuncs.prv;
1265void popShaderFlags(){
1267 ttglobal tg = gglobal();
1268 ppRenderFuncs p = (ppRenderFuncs)tg->RenderFuncs.prv;
1273struct X3D_Node* get_executionContext() {
1276 ttglobal tg = gglobal();
1277 ppRenderFuncs p = (ppRenderFuncs)tg->RenderFuncs.prv;
1278 if (p->ectx_stack->n)
1279 retval = stack_top(
struct X3D_Node*, p->ectx_stack);
1282void push_executionContext(
struct X3D_Node* broto) {
1284 ttglobal tg = gglobal();
1285 ppRenderFuncs p = (ppRenderFuncs)tg->RenderFuncs.prv;
1286 stack_push(
struct X3D_Node*, p->ectx_stack, broto);
1289void pop_executionContext() {
1291 ttglobal tg = gglobal();
1292 ppRenderFuncs p = (ppRenderFuncs)tg->RenderFuncs.prv;
1293 stack_pop(
struct X3D_Node*, p->ectx_stack);
1299 ttglobal tg = gglobal();
1300 ppRenderFuncs p = (ppRenderFuncs)tg->RenderFuncs.prv;
1302 retval = stack_top(
struct X3D_Node*,p->fog_stack);
1305void pushFogParams(
struct X3D_Node *fogparams){
1309 ttglobal tg = gglobal();
1310 ppRenderFuncs p = (ppRenderFuncs)tg->RenderFuncs.prv;
1311 stack_push(
struct X3D_Node*,p->fog_stack,fogparams);
1316 ttglobal tg = gglobal();
1317 ppRenderFuncs p = (ppRenderFuncs)tg->RenderFuncs.prv;
1318 stack_pop(
struct X3D_Node*,p->fog_stack);
1330 ttglobal tg = gglobal();
1331 ppRenderFuncs p = (ppRenderFuncs)tg->RenderFuncs.prv;
1337 stack_push(
struct point_XYZ3,p->ray_stack,p->t_r123);
1343 upd_ray0(&p->t_r123.p1,&p->t_r123.p2,&p->t_r123.p3);
1349 ttglobal tg = gglobal();
1350 ppRenderFuncs p = (ppRenderFuncs)tg->RenderFuncs.prv;
1354 p->t_r123 = stack_top(
struct point_XYZ3,p->ray_stack);
1362 ttglobal tg = gglobal();
1363 ppRenderFuncs p = (ppRenderFuncs)tg->RenderFuncs.prv;
1367void push_render_geom(
int igeom){
1368 ttglobal tg = gglobal();
1369 ppRenderFuncs p = (ppRenderFuncs)tg->RenderFuncs.prv;
1370 ttrenderstate rs = renderstate();
1371 stack_push(
int,p->render_geom_stack,rs->render_geom);
1372 rs->render_geom = igeom;
1374void pop_render_geom(){
1376 ttglobal tg = gglobal();
1377 ppRenderFuncs p = (ppRenderFuncs)tg->RenderFuncs.prv;
1378 igeom = stack_top(
int,p->render_geom_stack);
1379 stack_pop(
int,p->render_geom_stack);
1380 ttrenderstate rs = renderstate();
1381 rs->render_geom = igeom;
1383void push_sensor(
struct X3D_Node *node){
1384 ttglobal tg = gglobal();
1385 ppRenderFuncs p = (ppRenderFuncs)tg->RenderFuncs.prv;
1387 push_render_geom(1);
1388 stack_push(
struct currayhit,p->sensor_stack,p->rayph);
1392 p->rayph.hitNode = node;
1393 FW_GL_GETDOUBLEV(GL_MODELVIEW_MATRIX, p->rayph.modelMatrix);
1394 FW_GL_GETDOUBLEV(GL_PROJECTION_MATRIX, p->rayph.projMatrix);
1398 ttglobal tg = gglobal();
1399 ppRenderFuncs p = (ppRenderFuncs)tg->RenderFuncs.prv;
1403 p->rayph = stack_top(
struct currayhit,p->sensor_stack);
1404 stack_pop(
struct currayhit,p->sensor_stack);
1409int render_foundSelectedViewpoint();
1410void extent6f_draw(
float *extent);
1411static int draw_extents = TRUE;
1413void wrap_Shape(
struct X3D_Node* node);
1415void render_node(
struct X3D_Node *node) {
1425 ttglobal tg = gglobal();
1426 p = (ppRenderFuncs)tg->RenderFuncs.prv;
1428 X3D_NODE_CHECK(node);
1436 DEBUG_RENDER(
"%d no node, quick return\n", renderLevel);
1441 virt = virtTable[node->_nodeType];
1447 for(i=0;i<p->renderLevel;i++) printf(
" ");
1449 printf(
"%d node %u (%s) , v %u renderFlags %x ",p->renderLevel, node,stringNodeType(node->_nodeType),virt,node->_renderFlags);
1451 if ((node->_renderFlags & VF_Viewpoint) == VF_Viewpoint) printf (
" VF_Viewpoint");
1452 if ((node->_renderFlags & VF_Geom )== VF_Geom) printf (
" VF_Geom");
1453 if ((node->_renderFlags & VF_localLight )== VF_localLight) printf (
" VF_localLight");
1454 if ((node->_renderFlags & VF_Sensitive) == VF_Sensitive) printf (
" VF_Sensitive");
1455 if ((node->_renderFlags & VF_Blend) == VF_Blend) printf (
" VF_Blend");
1456 if ((node->_renderFlags & VF_Proximity) == VF_Proximity) printf (
" VF_Proximity");
1457 if ((node->_renderFlags & VF_Collision) == VF_Collision) printf (
" VF_Collision");
1458 if ((node->_renderFlags & VF_globalLight) == VF_globalLight) printf (
" VF_globalLight");
1459 if ((node->_renderFlags & VF_hasVisibleChildren) == VF_hasVisibleChildren) printf (
" VF_hasVisibleChildren");
1460 if ((node->_renderFlags & VF_shouldSortChildren) == VF_shouldSortChildren) printf (
" VF_shouldSortChildren");
1461 if ((node->_renderFlags & VF_Other) == VF_Other) printf (
" VF_Other");
1480 if (renderstate()->render_vp == VF_Viewpoint) {
1483 if (!is_vp_new_way()) {
1487 if ((node->_renderFlags & VF_Viewpoint) != VF_Viewpoint) {
1489 printf(
"doing Viewpoint, but this node is not for us - just returning\n");
1495 if(renderstate()->render_vp == VF_Viewpoint && render_foundSelectedViewpoint()){
1502 if (renderstate()->render_light) {
1503 if((node->_renderFlags & VF_globalLight) != VF_globalLight) {
1504 #ifdef RENDERVERBOSE
1505 printf (
"doing globalLight, but this node is not for us - just returning\n");
1511 justGeom = renderstate()->render_geom && !renderstate()->render_sensitive && !renderstate()->render_blend;
1513 pushed_sensor = FALSE;
1517 DEBUG_RENDER(
"rs 2\n");
1518 PRINT_GL_ERROR_IF_ANY(
"prep start"); PRINT_NODE(node, virt);
1519 profile_start(
"prep");
1521 profile_start(
"prepgeom");
1523 profile_end(
"prep");
1525 profile_end(
"prepgeom");
1530 PRINT_GL_ERROR_IF_ANY(
"prep end"); PRINT_NODE(node,virt);
1532 if(renderstate()->render_sensitive && !tg->RenderFuncs.hypersensitive) {
1536 if(renderstate()->render_proximity && virt->proximity) {
1537 DEBUG_RENDER(
"rs 2a\n");
1538 profile_start(
"proximity");
1539 virt->proximity(node);
1540 profile_end(
"proximity");
1541 PRINT_GL_ERROR_IF_ANY(
"render_proximity"); PRINT_NODE(node,virt);
1543 if(renderstate()->render_geom && ((node->_renderFlags & VF_USE) == VF_USE) && !renderstate()->render_picking){
1548 if(getWindex() == 0){
1552 double modelviewMatrix[16];
1555 FW_GL_GETDOUBLEV(GL_MODELVIEW_MATRIX, modelviewMatrix);
1557 usehit_add2(node,modelviewMatrix,getpickablegroupdata());
1560 if(renderstate()->render_picking && node->_nodeType == NODE_Shape ){
1564 double modelviewMatrix[16];
1566 if(shapenode->geometry){
1569 FW_GL_GETDOUBLEV(GL_MODELVIEW_MATRIX, modelviewMatrix);
1571 usehitB_add2(shapenode->geometry,modelviewMatrix,getpickablegroupdata());
1575 if(renderstate()->render_collision && virt->collision) {
1576 DEBUG_RENDER(
"rs 2b\n");
1577 profile_start(
"collision");
1578 virt->collision(node);
1579 profile_end(
"collision");
1580 PRINT_GL_ERROR_IF_ANY(
"render_collision"); PRINT_NODE(node,virt);
1583 if(renderstate()->render_geom && !renderstate()->render_sensitive && !renderstate()->render_picking && virt->rend) {
1584 DEBUG_RENDER(
"rs 3\n");
1585 PRINT_GL_ERROR_IF_ANY(
"BEFORE render_geom"); PRINT_NODE(node,virt);
1586 profile_start(
"rend");
1587 if (getSAI_X3DNodeType(node->_nodeType) == X3DGeometryNode && peek_shape() == NULL)
1592 profile_end(
"rend");
1593 PRINT_GL_ERROR_IF_ANY(
"render_geom"); PRINT_NODE(node,virt);
1595 if(renderstate()->render_other && virt->other )
1600 if(renderstate()->render_sensitive && ((node->_renderFlags & VF_Sensitive)|| Viewer()->LookatMode ==2)) {
1601 DEBUG_RENDER(
"rs 5\n");
1602 profile_start(
"sensitive");
1604 pushed_sensor = TRUE;
1605 profile_end(
"sensitive");
1607 if(renderstate()->render_geom && renderstate()->render_sensitive && !tg->RenderFuncs.hypersensitive && virt->rendray) {
1608 DEBUG_RENDER(
"rs 6\n");
1609 profile_start(
"rendray");
1610 if(pickrayHitsMBB(node))
1611 virt->rendray(node);
1612 profile_end(
"rendray");
1613 PRINT_GL_ERROR_IF_ANY(
"rs 6"); PRINT_NODE(node,virt);
1626 if(virt->children) {
1627 DEBUG_RENDER(
"rs 8 - has valid child node pointer\n");
1630 virt->children(node);
1635 PRINT_GL_ERROR_IF_ANY(
"children"); PRINT_NODE(node,virt);
1639 if(renderstate()->render_other && virt->other)
1647 DEBUG_RENDER(
"rs A\n");
1648 profile_start(
"fin");
1650 profile_start(
"fingeom");
1655 profile_end(
"fingeom");
1659 PRINT_GL_ERROR_IF_ANY(
"fin"); PRINT_NODE(node,virt);
1667 for(i=0;i<p->renderLevel;i++)printf(
" ");
1669 printf(
"%d (end render_node)\n",p->renderLevel);
1685void add_parent(
struct X3D_Node *node,
struct X3D_Node *parent,
char *file,
int line) {
1691 printf (
"add_parent; adding node %u ,to parent %u at %s:%d\n",node, parent,file,line);
1692 printf (
"add_parent; adding node %x ,to parent %x (hex) at %s:%d\n",node, parent,file,line);
1693 printf (
"add_parent; adding node %p ,to parent %p (ptr) at %s:%d\n",node, parent,file,line);
1696 printf (
"add_parent; adding node %u (%s) to parent %u (%s) at %s:%d\n",node, stringNodeType(node->_nodeType),
1697 parent, stringNodeType(parent->_nodeType),file,line);
1700 parent->_renderFlags = parent->_renderFlags | node->_renderFlags;
1703 for(
int i=0;i<node->_parentVector->n;i++)
1705 struct X3D_Node * parent2 = vector_get(
struct X3D_Node*,node->_parentVector,i);
1706 if(parent == parent2){
1711 vector_pushBack (
struct X3D_Node*,node->_parentVector, parent);
1713 itype = getTypeNode(node);
1715 setSensitive (parent, itype );
1731 for (i=0; i<vectorSize(child->_parentVector); i++) {
1732 struct X3D_Node *n = vector_get(
struct X3D_Node *, child->_parentVector,i);
1734 if (n==parent) pi = i;
1740 struct X3D_Node *n = vector_get(
struct X3D_Node *, child->_parentVector,vectorSize(child->_parentVector)-1);
1743 vector_set(
struct X3D_Node*, child->_parentVector, pi,n);
1746 vector_popBack(
struct X3D_Node*, child->_parentVector);
1758#include "../x3d_parser/Bindable.h"
1759int fwl_getShadingStyle();
1760void push_globalRenderFlags(){
1764 ttglobal tg = gglobal();
1765 shaderflags = getShaderFlags();
1769 if(vectorSize(getActiveBindableStacks(tg)->fog) > 0){
1771 struct X3D_Fog *fog = stack_top(
struct X3D_Fog*,getActiveBindableStacks(tg)->fog);
1772 if(fog->visibilityRange > 0.0f){
1775 shaderflags.base |= FOG_APPEARANCE_SHADER;
1777 pushFogParams((
struct X3D_Node*)fog);
1781 if(Viewer()->anaglyph || Viewer()->anaglyphB)
1782 shaderflags.base |= WANT_ANAGLYPH;
1785 switch(fwl_getShadingStyle()){
1786 case 0: shaderflags.base |= SHADINGSTYLE_FLAT;
break;
1787 case 1: shaderflags.base |= SHADINGSTYLE_GOURAUD;
break;
1788 case 2: shaderflags.base |= SHADINGSTYLE_PHONG;
break;
1789 case 3: shaderflags.base |= SHADINGSTYLE_WIRE;
break;
1791 shaderflags.base |= SHADINGSTYLE_PHONG;
break;
1793 if(tg->Component_TextureProjector.globalProjector){
1794 shaderflags.base |= HAVE_PROJECTIVETEXTURE;
1796 pushShaderFlags(shaderflags);
1798void pop_globalRenderFlags(){
1800 ttglobal tg = gglobal();
1805 if(vectorSize(getActiveBindableStacks(tg)->fog) > 0){
1806 struct X3D_Fog *fog = stack_top(
struct X3D_Fog*,getActiveBindableStacks(tg)->fog);
1807 if(fog->visibilityRange > 0.0f){
1813 tg->Component_TextureProjector.globalProjector = 0;
1819} what_strings [] = {
1820{VF_Viewpoint,
"Viewpoint"},
1822{VF_globalLight,
"globalLight"},
1823{VF_Sensitive,
"Sensitive"},
1824{VF_Picking,
"Picking"},
1826{VF_Proximity,
"Proximit"},
1827{VF_Collision,
"Collision"},
1830{VF_Background,
"Background"},
1833void rwhat_printf(
int rwhat){
1836 ws = &what_strings[k];
1838 if(rwhat & ws->iwhat) printf(
"%s ",ws->cwhat);
1840 ws = &what_strings[k];
1842 if (k) printf(
"\n");
1845void render_headlight();
1846void clear_vp_reachable_flags();
1847void render_hier(
struct X3D_Node *g,
int rwhat) {
1853 ttglobal tg = gglobal();
1855 p = (ppRenderFuncs)tg->RenderFuncs.prv;
1858 pushShaderFlags(shaderflags);
1875 rs->render_vp = rwhat & VF_Viewpoint;
1876 rs->render_geom = rwhat & VF_Geom;
1877 rs->render_light = rwhat & VF_globalLight;
1878 rs->render_sensitive = rwhat & VF_Sensitive;
1879 rs->render_picking = rwhat & VF_Picking;
1880 rs->render_blend = rwhat & VF_Blend;
1881 rs->render_proximity = rwhat & VF_Proximity;
1882 rs->render_collision = rwhat & VF_Collision;
1883 rs->render_other = rwhat & VF_Other;
1884 rs->render_cube = rwhat & VF_Cube;
1885 rs->render_background = rwhat & VF_Background;
1886 rs->render_depth = rwhat & VF_Depth;
1892 tg->RenderFuncs.hitPointDist = -1;
1896 printf (
"render_hier vp %d geom %d light %d sens %d blend %d prox %d col %d\n",
1897 rs->render_vp,rs->render_geom,rs->render_light,rs->render_sensitive,rs->render_blend,rs->render_proximity,rs->render_collision);
1907 printf(
"Render_hier node=%d what=%d\n", g, rwhat);
1910 if (rs->render_light) {
1913 if (rs->render_sensitive) {
1916 if(rs->render_blend || rs->render_geom){
1917 push_globalRenderFlags();
1919 profile_start(
"render_hier");
1921 render_node(X3D_NODE(g));
1924 profile_end(
"render_hier");
1925 if(rs->render_blend || rs->render_geom){
1926 pop_globalRenderFlags();
1932void render_hier2(
struct X3D_Node* g,
int rwhat) {
1937 ttglobal tg = gglobal();
1939 p = (ppRenderFuncs)tg->RenderFuncs.prv;
1940 push_new_renderstate();
1943 pushShaderFlags(shaderflags);
1960 rs->render_vp = rwhat & VF_Viewpoint;
1961 rs->render_geom = rwhat & VF_Geom;
1962 rs->render_light = rwhat & VF_globalLight;
1963 rs->render_sensitive = rwhat & VF_Sensitive;
1964 rs->render_picking = rwhat & VF_Picking;
1965 rs->render_blend = rwhat & VF_Blend;
1966 rs->render_proximity = rwhat & VF_Proximity;
1967 rs->render_collision = rwhat & VF_Collision;
1968 rs->render_other = rwhat & VF_Other;
1969 rs->render_cube = rwhat & VF_Cube;
1970 rs->render_background = rwhat & VF_Background;
1971 rs->render_depth = rwhat & VF_Depth;
1980 printf(
"render_hier vp %d geom %d light %d sens %d blend %d prox %d col %d\n",
1981 rs->render_vp, rs->render_geom, rs->render_light, rs->render_sensitive, rs->render_blend, rs->render_proximity, rs->render_collision);
1991 printf(
"Render_hier node=%d what=%d\n", g, rwhat);
1994 if (rs->render_light) {
2007 render_node(X3D_NODE(g));
2018void clear_renderstate(){
2020 ttglobal tg = gglobal();
2022 p = (ppRenderFuncs)tg->RenderFuncs.prv;
2024 memset(rs,0,
sizeof(ttrenderstate));
2033void compileNode (
void (*nodefn)(
void *,
void *,
void *,
void *,
void *,
void *),
void *node,
void *Icoord,
void *IfogCoord,
void *Icolor,
void *Inormal,
void *ItexCoord) {
2034 void *coord;
void *fogCoord;
void *color;
void *normal;
void *texCoord;
2037 POSSIBLE_PROTO_EXPANSION(
void *, Icoord,coord)
2038 POSSIBLE_PROTO_EXPANSION(
void *, IfogCoord,fogCoord)
2039 POSSIBLE_PROTO_EXPANSION(
void *, Icolor,color)
2040 POSSIBLE_PROTO_EXPANSION(
void *, Inormal,normal)
2041 POSSIBLE_PROTO_EXPANSION(
void *, ItexCoord,texCoord)
2043 nodefn(node, coord, fogCoord, color, normal, texCoord);
2046void do_NurbsPositionInterpolator (
void *node);
2047void do_NurbsOrientationInterpolator (
void *node);
2048void do_NurbsSurfaceInterpolator (
void *node);
2051void *returnInterpolatorPointer (
int nodeType) {
2052 void (*do_interp)(
void *);
2056 case NODE_OrientationInterpolator: do_interp = do_Oint4;
break;
2057 case NODE_CoordinateInterpolator2D: do_interp = do_OintCoord2D;
break;
2058 case NODE_PositionInterpolator2D: do_interp = do_OintPos2D;
break;
2059 case NODE_ScalarInterpolator: do_interp = do_OintScalar;
break;
2060 case NODE_ColorInterpolator: do_interp = do_ColorInterpolator;
break;
2061 case NODE_PositionInterpolator: do_interp = do_PositionInterpolator;
break;
2062 case NODE_CoordinateInterpolator: do_interp = do_OintCoord;
break;
2063 case NODE_VectorInterpolator: do_interp = do_OintVector;
break;
2064 case NODE_CoordinateMorpher: do_interp = do_CoordinateMorph;
break;
2065 case NODE_NormalMorpher: do_interp = do_NormalMorph;
break;
2066 case NODE_NormalInterpolator: do_interp = do_OintNormal;
break;
2067 case NODE_EaseInEaseOut: do_interp = do_EaseInEaseOut;
break;
2068 case NODE_SplinePositionInterpolator: do_interp = do_SplinePositionInterpolator;
break;
2069 case NODE_SplinePositionInterpolator2D: do_interp = do_SplinePositionInterpolator2D;
break;
2070 case NODE_SplineScalarInterpolator: do_interp = do_SplineScalarInterpolator;
break;
2071 case NODE_SquadOrientationInterpolator: do_interp = do_SquadOrientationInterpolator;
break;
2072 case NODE_GeoPositionInterpolator: do_interp = do_GeoPositionInterpolator;
break;
2073 case NODE_NurbsPositionInterpolator: do_interp = do_NurbsPositionInterpolator;
break;
2074 case NODE_NurbsOrientationInterpolator: do_interp = do_NurbsOrientationInterpolator;
break;
2075 case NODE_NurbsSurfaceInterpolator: do_interp = do_NurbsSurfaceInterpolator;
break;
2076 case NODE_BooleanFilter: do_interp = do_BooleanFilter;
break;
2077 case NODE_BooleanSequencer: do_interp = do_BooleanSequencer;
break;
2078 case NODE_BooleanToggle: do_interp = do_BooleanToggle;
break;
2079 case NODE_BooleanTrigger: do_interp = do_BooleanTrigger;
break;
2080 case NODE_IntegerTrigger: do_interp = do_IntegerTrigger;
break;
2081 case NODE_IntegerSequencer: do_interp = do_IntegerSequencer;
break;
2082 case NODE_TimeTrigger: do_interp = do_TimeTrigger;
break;
2083 case NODE_GeoConvert: do_interp = do_GeoConvert;
break;
2087 return (
void *)do_interp;
2128 if (node == NULL)
return;
2132 if (parent != NULL) ADD_PARENT(node, parent);
2134 if ((node->_nodeType<0) || (node->_nodeType>NODES_COUNT)) {
2135 ConsoleMessage (
"checkParentLink - %d not a valid nodeType",node->_nodeType);
2140 offsetptr = (
int *) NODE_OFFSETS[node->_nodeType];
2143 while (*offsetptr >= 0) {
2153 if ((offsetptr[2] == FIELDTYPE_SFNode) || (offsetptr[2] == FIELDTYPE_MFNode)) {
2154 if ((offsetptr[3] == KW_initializeOnly) || (offsetptr[3] == KW_inputOutput)) {
2157 memptr = (
char *) node;
2158 memptr += offsetptr[1];
2160 if (offsetptr[2] == FIELDTYPE_SFNode) {
2162 voidptr = (uintptr_t *) memptr;
2163 voidptr = (uintptr_t *) *voidptr;
2166 if (voidptr != NULL) {
2167 checkParentLink(X3D_NODE(voidptr),node);
2172 for (n=0; n<mfn->n; n++) {
2173 checkParentLink(mfn->p[n],node);
2179 offsetptr += FIELDOFFSET_LENGTH;
2183#define X3D_COORD(node) ((struct X3D_Coordinate*)node)
2184#define X3D_GEOCOORD(node) ((struct X3D_GeoCoordinate*)node)
2192 POSSIBLE_PROTO_EXPANSION (
struct X3D_Node *, innode,node)
2195 xc = X3D_COORD(node);
2197 if (xc->_nodeType == NODE_Coordinate) {
2198 return &(xc->point);
2199 }
else if (xc->_nodeType == NODE_GeoCoordinate) {
2200 COMPILE_IF_REQUIRED_RETURN_NULL_ON_ERROR;
2201 gxc = X3D_GEOCOORD(node);
2202 return &(gxc->__movedCoords);
2204 ConsoleMessage (
"%s - coord expected but got %s\n", stringNodeType(xc->_nodeType));