]> git.jsancho.org Git - guile-irrlicht.git/blob - src/scene-manager.cpp
51e561ad4c5159861294c5d03e8dc63dde7689cb
[guile-irrlicht.git] / src / scene-manager.cpp
1 /* guile-irrlicht --- GNU Guile bindings for Irrlicht Engine
2
3    Copyright (C) 2020 Javier Sancho <jsf@jsancho.org>
4
5    This file is part of guile-irrlicht.
6
7    guile-irrlicht is free software; you can redistribute it and/or modify
8    it under the terms of the GNU Lesser General Public License as
9    published by the Free Software Foundation; either version 3 of the
10    License, or (at your option) any later version.
11
12    guile-irrlicht is distributed in the hope that it will be useful, but
13    WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15    General Public License for more details.
16
17    You should have received a copy of the GNU Lesser General Public
18    License along with guile-irrlicht. If not, see
19    <http://www.gnu.org/licenses/>.
20 */
21
22 #include <irrlicht/irrlicht.h>
23 #include <libguile.h>
24 #include "gsubr.h"
25 #include "scene-manager.h"
26 #include "vector3d.h"
27
28
29 using namespace irr;
30
31
32 template <typename TParent>
33 SCM
34 scene_ISceneManager_addAnimatedMeshSceneNode (SCM scene_manager,
35                                               SCM mesh,
36                                               SCM parent,
37                                               SCM id,
38                                               SCM position,
39                                               SCM rotation,
40                                               SCM scale,
41                                               SCM also_add_if_mesh_pointer_zero)
42 {
43   scene::ISceneManager* smgr = (scene::ISceneManager*) scm_to_pointer (scene_manager);
44   scene::IAnimatedMeshSceneNode* node =
45     smgr->addAnimatedMeshSceneNode ((scene::IAnimatedMesh*) scm_to_pointer (mesh),
46                                     (TParent) scm_to_pointer (parent),
47                                     scm_to_int32 (id),
48                                     scm_to_vector3df (position),
49                                     scm_to_vector3df (rotation),
50                                     scm_to_vector3df (scale),
51                                     scm_to_bool (also_add_if_mesh_pointer_zero));
52   return scm_from_pointer ((void*) node, NULL);
53 }
54
55
56 template <typename TParent>
57 SCM
58 scene_ISceneManager_addCameraSceneNode (SCM scene_manager,
59                                         SCM parent,
60                                         SCM position,
61                                         SCM lookat,
62                                         SCM id,
63                                         SCM make_active)
64 {
65   scene::ISceneManager* smgr = (scene::ISceneManager*) scm_to_pointer (scene_manager);
66   scene::ICameraSceneNode* camera =
67     smgr->addCameraSceneNode ((TParent) scm_to_pointer (parent),
68                               scm_to_vector3df (position),
69                               scm_to_vector3df (lookat),
70                               scm_to_int32 (id),
71                               scm_to_bool (make_active));
72   return scm_from_pointer ((void*) camera, NULL);
73 }
74
75
76 template <typename TParent>
77 SCM
78 scene_ISceneManager_addCameraSceneNodeFPS (SCM scene_manager,
79                                            SCM rest)
80 {
81   SCM parent;
82   SCM rotate_speed;
83   SCM move_speed;
84   SCM id;
85   SCM key_map_array;
86   SCM key_map_size;
87   SCM no_vertical_movement;
88   SCM jump_speed;
89   SCM invert_mouse;
90   SCM make_active;
91
92   scm_c_bind_keyword_arguments ("scene_ISceneManager_addCameraSceneNodeFPS",
93                                 rest, (scm_t_keyword_arguments_flags)0,
94                                 scm_from_utf8_keyword ("parent"), &parent,
95                                 scm_from_utf8_keyword ("rotate-speed"), &rotate_speed,
96                                 scm_from_utf8_keyword ("move-speed"), &move_speed,
97                                 scm_from_utf8_keyword ("id"), &id,
98                                 scm_from_utf8_keyword ("key-map-array"), &key_map_array,
99                                 scm_from_utf8_keyword ("key-map-size"), &key_map_size,
100                                 scm_from_utf8_keyword ("no-vertical-movement"), &no_vertical_movement,
101                                 scm_from_utf8_keyword ("jump-speed"), &jump_speed,
102                                 scm_from_utf8_keyword ("invert-mouse"), &invert_mouse,
103                                 scm_from_utf8_keyword ("make-active"), &make_active,
104                                 SCM_UNDEFINED);
105
106   scene::ISceneManager* smgr = (scene::ISceneManager*) scm_to_pointer (scene_manager);
107   scene::ICameraSceneNode* camera =
108     smgr->addCameraSceneNodeFPS ((TParent) scm_to_pointer (parent),
109                                  scm_to_double (rotate_speed),
110                                  scm_to_double (move_speed),
111                                  scm_to_int32 (id),
112                                  (SKeyMap*) scm_to_pointer (key_map_array),
113                                  scm_to_int32 (key_map_size),
114                                  scm_to_bool (no_vertical_movement),
115                                  scm_to_double (jump_speed),
116                                  scm_to_bool (invert_mouse),
117                                  scm_to_bool (make_active));
118   return scm_from_pointer ((void*) camera, NULL);
119 }
120
121
122 template <typename TParent>
123 SCM
124 scene_ISceneManager_addCubeSceneNode (SCM scene_manager,
125                                       SCM size,
126                                       SCM parent,
127                                       SCM id,
128                                       SCM position,
129                                       SCM rotation,
130                                       SCM scale)
131 {
132   scene::ISceneManager* smgr = (scene::ISceneManager*) scm_to_pointer (scene_manager);
133   scene::IMeshSceneNode* node =
134     smgr->addCubeSceneNode (scm_to_double (size),
135                             (TParent) scm_to_pointer (parent),
136                             scm_to_int32 (id),
137                             scm_to_vector3df (position),
138                             scm_to_vector3df (rotation),
139                             scm_to_vector3df (scale));
140   return scm_from_pointer ((void*) node, NULL);
141 }
142
143
144 template <typename TParent>
145 SCM
146 scene_ISceneManager_addCustomSceneNode (SCM scene_manager,
147                                         SCM proc_render,
148                                         SCM proc_get_bounding_box,
149                                         SCM proc_get_material_count,
150                                         SCM proc_get_material,
151                                         SCM parent,
152                                         SCM id,
153                                         SCM position,
154                                         SCM rotation,
155                                         SCM scale)
156 {
157   class CustomSceneNode : public scene::ISceneNode
158   {
159     SCM scm_render;
160     SCM scm_get_bounding_box;
161     SCM scm_get_material_count;
162     SCM scm_get_material;
163
164   public:
165     CustomSceneNode (scene::ISceneNode* parent,
166                      scene::ISceneManager* smgr,
167                      s32 id,
168                      const core::vector3df& position,
169                      const core::vector3df& rotation,
170                      const core::vector3df& scale,
171                      SCM render,
172                      SCM get_bounding_box,
173                      SCM get_material_count,
174                      SCM get_material)
175       : scene::ISceneNode (parent, smgr, id, position, rotation, scale)
176     {
177       scm_render = render;
178       scm_get_bounding_box = get_bounding_box;
179       scm_get_material_count = get_material_count;
180       scm_get_material = get_material;
181     }
182
183     virtual void OnRegisterSceneNode ()
184     {
185       if (IsVisible)
186         {
187           SceneManager->registerNodeForRendering (this);
188         }
189       ISceneNode::OnRegisterSceneNode ();
190     }
191
192     virtual void render ()
193     {
194       scm_call_0 (scm_render);
195     }
196
197     virtual const core::aabbox3d<f32>& getBoundingBox () const
198     {
199       SCM box = scm_call_0 (scm_get_bounding_box);
200       return *((core::aabbox3d<f32>*) scm_to_pointer (box));
201     }
202
203     virtual u32 getMaterialCount () const
204     {
205       return scm_to_uint32 (scm_call_0 (scm_get_material_count));
206     }
207
208     virtual video::SMaterial& getMaterial (u32 i)
209     {
210       SCM material = scm_call_1 (scm_get_material, scm_from_uint32 (i));
211       return *((video::SMaterial*) scm_to_pointer (material));
212     }
213   };
214
215   CustomSceneNode* node =
216     new CustomSceneNode ((TParent) scm_to_pointer (parent),
217                          (scene::ISceneManager*) scm_to_pointer (scene_manager),
218                          scm_to_int32 (id),
219                          scm_to_vector3df (position),
220                          scm_to_vector3df (rotation),
221                          scm_to_vector3df (scale),
222                          proc_render,
223                          proc_get_bounding_box,
224                          proc_get_material_count,
225                          proc_get_material);
226   return scm_from_pointer ((void*) node, NULL);
227 }
228
229
230 template <typename TParent, typename TMesh>
231 SCM
232 scene_ISceneManager_addOctreeSceneNode (SCM scene_manager,
233                                         SCM mesh,
234                                         SCM parent,
235                                         SCM id,
236                                         SCM minimal_polys_per_node,
237                                         SCM also_add_if_mesh_pointer_zero)
238 {
239   scene::ISceneManager* smgr = (scene::ISceneManager*) scm_to_pointer (scene_manager);
240   scene::IMeshSceneNode* node =
241     smgr->addOctreeSceneNode ((TMesh) scm_to_pointer (mesh),
242                               (TParent) scm_to_pointer (parent),
243                               scm_to_int32 (id),
244                               scm_to_int32 (minimal_polys_per_node),
245                               scm_to_bool (also_add_if_mesh_pointer_zero));
246   return scm_from_pointer ((void*) node, NULL);
247 }
248
249
250 template <typename TParent>
251 SCM
252 scene_ISceneManager_addSphereSceneNode (SCM scene_manager,
253                                         SCM radius,
254                                         SCM poly_count,
255                                         SCM parent,
256                                         SCM id,
257                                         SCM position,
258                                         SCM rotation,
259                                         SCM scale)
260 {
261   scene::ISceneManager* smgr = (scene::ISceneManager*) scm_to_pointer (scene_manager);
262   scene::IMeshSceneNode* node =
263     smgr->addSphereSceneNode (scm_to_double (radius),
264                               scm_to_int32 (poly_count),
265                               (TParent) scm_to_pointer (parent),
266                               scm_to_int32 (id),
267                               scm_to_vector3df (position),
268                               scm_to_vector3df (rotation),
269                               scm_to_vector3df (scale));
270   return scm_from_pointer ((void*) node, NULL);
271 }
272
273
274 SCM
275 scene_ISceneManager_createFlyCircleAnimator (SCM scene_manager,
276                                              SCM center,
277                                              SCM radius,
278                                              SCM speed,
279                                              SCM direction,
280                                              SCM start_position,
281                                              SCM radius_ellipsoid)
282 {
283   scene::ISceneManager* smgr = (scene::ISceneManager*) scm_to_pointer (scene_manager);
284   scene::ISceneNodeAnimator* anim =
285     smgr->createFlyCircleAnimator (scm_to_vector3df (center),
286                                    scm_to_double (radius),
287                                    scm_to_double (speed),
288                                    scm_to_vector3df (direction),
289                                    scm_to_double (start_position),
290                                    scm_to_double (radius_ellipsoid));
291   return scm_from_pointer ((void*) anim, NULL);
292 }
293
294
295 SCM
296 scene_ISceneManager_createFlyStraightAnimator (SCM scene_manager,
297                                                SCM start_point,
298                                                SCM end_point,
299                                                SCM time_for_way,
300                                                SCM loop,
301                                                SCM pingpong)
302 {
303   scene::ISceneManager* smgr = (scene::ISceneManager*) scm_to_pointer (scene_manager);
304   scene::ISceneNodeAnimator* anim =
305     smgr->createFlyStraightAnimator (scm_to_vector3df (start_point),
306                                      scm_to_vector3df (end_point),
307                                      scm_to_uint32 (time_for_way),
308                                      scm_to_bool (loop),
309                                      scm_to_bool (pingpong));
310   return scm_from_pointer ((void*) anim, NULL);
311 }
312
313
314 SCM
315 scene_ISceneManager_createRotationAnimator (SCM scene_manager,
316                                             SCM rotation_speed)
317 {
318   scene::ISceneManager* smgr = (scene::ISceneManager*) scm_to_pointer (scene_manager);
319   scene::ISceneNodeAnimator* anim =
320     smgr->createRotationAnimator (scm_to_vector3df (rotation_speed));
321   return scm_from_pointer ((void*) anim, NULL);
322 }
323
324
325 SCM
326 scene_ISceneManager_drawAll (SCM scene_manager)
327 {
328   ((scene::ISceneManager*) scm_to_pointer (scene_manager))->drawAll ();
329   return SCM_UNSPECIFIED;
330 }
331
332
333 SCM
334 scene_ISceneManager_getMesh (SCM scene_manager,
335                              SCM filename)
336 {
337   scene::ISceneManager* smgr = (scene::ISceneManager*) scm_to_pointer (scene_manager);
338   scene::IAnimatedMesh* mesh = smgr->getMesh(scm_to_utf8_stringn (filename, NULL));
339   return scm_from_pointer ((void*) mesh, NULL);
340 }
341
342
343 SCM
344 scene_ISceneManager_getRootSceneNode (SCM scene_manager)
345 {
346   scene::ISceneManager* smgr = (scene::ISceneManager*) scm_to_pointer (scene_manager);
347   return scm_from_pointer ((void*) smgr->getRootSceneNode (), NULL);
348 }
349
350
351 extern "C" {
352
353   void
354   init_scene_manager (void)
355   {
356     DEFINE_GSUBR ("scene_ISceneManager_addAnimatedMeshSceneNode_ISceneNode", 8, 0, 0,
357                   scene_ISceneManager_addAnimatedMeshSceneNode<scene::ISceneNode*>);
358     DEFINE_GSUBR ("scene_ISceneManager_addCameraSceneNode_ISceneNode", 6, 0, 0,
359                   scene_ISceneManager_addCameraSceneNode<scene::ISceneNode*>);
360     DEFINE_GSUBR ("scene_ISceneManager_addCameraSceneNodeFPS_ISceneNode", 1, 0, 1,
361                   scene_ISceneManager_addCameraSceneNodeFPS<scene::ISceneNode*>);
362     DEFINE_GSUBR ("scene_ISceneManager_addCubeSceneNode_ISceneNode", 7, 0, 0,
363                   scene_ISceneManager_addCubeSceneNode<scene::ISceneNode*>);
364     DEFINE_GSUBR ("scene_ISceneManager_addCustomSceneNode_ISceneNode", 10, 0, 0,
365                   scene_ISceneManager_addCustomSceneNode<scene::ISceneNode*>);
366     DEFINE_GSUBR ("scene_ISceneManager_addOctreeSceneNode_ISceneNode_IAnimatedMesh", 6, 0, 0,
367                   (scene_ISceneManager_addOctreeSceneNode<scene::ISceneNode*, scene::IAnimatedMesh*>));
368     DEFINE_GSUBR ("scene_ISceneManager_addOctreeSceneNode_ISceneNode_IMesh", 6, 0, 0,
369                   (scene_ISceneManager_addOctreeSceneNode<scene::ISceneNode*, scene::IMesh*>));
370     DEFINE_GSUBR ("scene_ISceneManager_addSphereSceneNode_ISceneNode", 8, 0, 0,
371                   scene_ISceneManager_addSphereSceneNode<scene::ISceneNode*>);
372     DEFINE_GSUBR ("scene_ISceneManager_createFlyCircleAnimator", 7, 0, 0,
373                   scene_ISceneManager_createFlyCircleAnimator);
374     DEFINE_GSUBR ("scene_ISceneManager_createFlyStraightAnimator", 6, 0, 0,
375                   scene_ISceneManager_createFlyStraightAnimator);
376     DEFINE_GSUBR ("scene_ISceneManager_createRotationAnimator", 2, 0, 0,
377                   scene_ISceneManager_createRotationAnimator);
378     DEFINE_GSUBR ("scene_ISceneManager_drawAll", 1, 0, 0, scene_ISceneManager_drawAll);
379     DEFINE_GSUBR ("scene_ISceneManager_getMesh", 2, 0, 0, scene_ISceneManager_getMesh);
380     DEFINE_GSUBR ("scene_ISceneManager_getRootSceneNode", 1, 0, 0,
381                   scene_ISceneManager_getRootSceneNode);
382   }
383
384 }