1 /*
2  * NodeCattExportRec.cpp
3  *
4  * Copyright (C) 2007 J. "MUFTI" Scheurich
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program (see the file "COPYING" for details); if
18  * not, write to the Free Software Foundation, Inc., 675 Mass Ave,
19  * Cambridge, MA 02139, USA.
20  */
21 
22 #include <stdio.h>
23 #include "stdafx.h"
24 
25 #include <sys/types.h>
26 #include <sys/stat.h>
27 #ifndef _WIN32
28 # include <fcntl.h>
29 #endif
30 
31 #include "NodeCattExportRec.h"
32 #include "Scene.h"
33 #include "Proto.h"
34 #include "RenderState.h"
35 #include "Util.h"
36 #include "swt.h"
37 #include "NodeNavigationInfo.h"
38 
39 enum {
40     RECEIVER_LOCATION
41 };
42 
ProtoCattExportRec(Scene * scene)43 ProtoCattExportRec::ProtoCattExportRec(Scene *scene)
44   : Proto(scene, "CattExportRec")
45 {
46     id.set(
47          addField(SFINT32, "id", new SFInt32(1)));
48 
49     receiverLocation.set(
50          addExposedField(SFVEC3F, "receiverLocation", new SFVec3f(0, 0, 0)));
51 
52     furtherParameters.set(
53          addField(SFSTRING, "furtherParameters", new SFString("")));
54 
55     addURLs(URL_EXPORT_CONTAINER);
56 }
57 
58 Node *
create(Scene * scene)59 ProtoCattExportRec::create(Scene *scene)
60 {
61     return new NodeCattExportRec(scene, this);
62 }
63 
NodeCattExportRec(Scene * scene,Proto * def)64 NodeCattExportRec::NodeCattExportRec(Scene *scene, Proto *def)
65   : Node(scene, def)
66 {
67 }
68 
69 int
writeProto(int f)70 NodeCattExportRec::writeProto(int f)
71 {
72     return ((Node *)this)->writeProto(f, "", "exportContainers"
73 #ifdef HAVE_EXPORT_CONTAINER_PROTO_URL
74                                       , HAVE_EXPORT_CONTAINER_PROTO_URL
75 #endif
76                                      );
77 }
78 
79 void
drawHandles()80 NodeCattExportRec::drawHandles()
81 {
82     glPushMatrix();
83     glPushAttrib(GL_LIGHTING);
84     glDisable(GL_LIGHTING);
85     Vec3f loc(receiverLocation()->getValue());
86 
87     glPushName(RECEIVER_LOCATION);
88     glLoadName(RECEIVER_LOCATION);
89 
90     RenderState state;
91 
92     Util::myGlColor3f(1.0f, 1.0f, 1.0f);
93     state.startDrawHandles();
94     state.drawHandle(loc);
95     state.endDrawHandles();
96     glPopName();
97     glPopAttrib();
98 
99     glPopMatrix();
100 }
101 
102 Vec3f
getHandle(int handle,int * constraint,int * field)103 NodeCattExportRec::getHandle(int handle, int *constraint, int *field)
104 {
105     if (handle == RECEIVER_LOCATION) {
106         *field = receiverLocation_Field();
107         return receiverLocation()->getValue();
108     }
109     *field = getProto()->metadata_Field();
110     return Vec3f(0.0f, 0.0f, 0.0f);
111 }
112 
113 void
setHandle(int handle,const Vec3f & v)114 NodeCattExportRec::setHandle(int handle, const Vec3f &v)
115 {
116     if (handle == RECEIVER_LOCATION)
117         m_scene->setField(this, receiverLocation_Field(), new SFVec3f(v));
118 }
119 
120 void
setField(int index,FieldValue * value,int cf)121 NodeCattExportRec::setField(int index, FieldValue *value, int cf)
122 {
123     Node::setField(index, value, cf);
124     update();
125 }
126 
127 void
preDraw()128 NodeCattExportRec::preDraw()
129 {
130 }
131 
132 void
draw(int pass)133 NodeCattExportRec::draw(int pass)
134 {
135     if (pass == RENDER_PASS_TRANSPARENT)
136         return;
137 
138     const float *loc =  receiverLocation()->getValue();
139 
140     float black[4] = { 0.0f, 0.0f, 0.0f, 1.0f };
141 
142     glPushMatrix();
143     glTranslatef(loc[0], loc[1], loc[2]);
144 
145     float scale = TheApp->GetHandleScale() *
146                    m_scene->getNavigationInfoNode()->speed()->getValue();
147     glScalef(scale, scale, scale);
148 
149     glPushName(RECEIVER_LOCATION);
150 
151     glEnable(GL_CULL_FACE);
152 
153     Util::myGlMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, black);
154     Util::myGlMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, black);
155 
156     GLUquadricObj *obj = gluNewQuadric();
157 
158     glLoadName(RECEIVER_LOCATION);
159     float color[4] = {1.0f, 1.0f, 1.0f, 1.0f};
160 
161     Util::myGlMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, color);
162 
163     glPushMatrix();
164     glRotatef(-90.0f, 1.0f, 0.0f, 0.0f);
165     glTranslatef(0.0f, 0.0f, -0.1);
166     gluQuadricOrientation(obj, GLU_INSIDE);
167     gluDisk(obj, 0.0, 0.07, 10, 1);
168     gluQuadricOrientation(obj, GLU_OUTSIDE);
169     gluCylinder(obj, 0.07, 0.07, 0.2, 10, 10);
170     glTranslatef(0.0f, 0.0f, 0.2);
171     gluDisk(obj, 0.0, 0.07, 10, 1);
172     glPopMatrix();
173 
174     gluDeleteQuadric(obj);
175     glPopName();
176 
177     glDisable(GL_CULL_FACE);
178 
179     glPopMatrix();
180 
181 }
182 
183 int
writeCattGeo(int filedes,int indent)184 NodeCattExportRec::writeCattGeo(int filedes, int indent)
185 {
186     if (!TheApp->GetCattExportSrcRec()) {
187          const char *message = "Warning: CattExportRec not written, see Options -> output settings...\n";
188          TheApp->PrintMessageWindows(message);
189          swDebugf("%s", message);
190          return 0;
191     }
192     const char *path = TheApp->GetCattExportPath();
193     int len = strlen(path)+256;
194     char *filename = new char[len];
195     mysnprintf(filename, len - 1, "%sRec.loc", path);
196     int openflags = O_WRONLY | O_CREAT;
197     if (m_scene->getCattRecIsWritten())
198         openflags = O_RDWR | O_APPEND;
199     int f = open(filename, openflags, 00666);
200     if (f == -1)
201         return -1;
202     delete [] filename;
203     if (m_scene->getCattRecIsWritten())
204         lseek(f, 0, SEEK_END); // O_APPEND seams not to work under M$Windows...
205 
206     if (!m_scene->getCattRecIsWritten()) {
207         RET_ONERROR( mywritestr(f, "RECEIVERS") )
208         RET_ONERROR( mywritestr(f, swGetLinefeedString()) )
209     }
210 
211     RET_ONERROR( mywritef(f, "%d ", id()->getValue()) )
212     const float *loc =  receiverLocation()->getValue();
213     glPushMatrix();
214     Matrix matrix;
215     glGetFloatv(GL_MODELVIEW_MATRIX, (GLfloat *) matrix);
216     glPopMatrix();
217     Vec3f v = matrix * Vec3f(loc);
218     RET_ONERROR( mywritef(f, "%g %g %g", v.x, v.z, v.y) )
219 
220     const char* rest = furtherParameters()->getValue();
221     RET_ONERROR( mywritef(f, " %s", rest) )
222 
223     RET_ONERROR( mywritestr(f, swGetLinefeedString()) )
224 
225     m_scene->setCattRecIsWritten();
226     return swTruncateClose(f);
227 }
228 
229