]> git.jsancho.org Git - guile-irrlicht.git/blob - src/scene-manager.cpp
427faf57c5e7fb0b9031086d2d2412e2fe5b8b65
[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 using namespace irr;
29
30 template <typename TParent>
31 SCM
32 ISceneManager_addAnimatedMeshSceneNode (SCM scene_manager,
33                                         SCM mesh,
34                                         SCM parent,
35                                         SCM id,
36                                         SCM position,
37                                         SCM rotation,
38                                         SCM scale,
39                                         SCM also_add_if_mesh_pointer_zero)
40 {
41   scene::ISceneManager* smgr = (scene::ISceneManager*) scm_to_pointer (scene_manager);
42   scene::IAnimatedMeshSceneNode* node =
43     smgr->addAnimatedMeshSceneNode ((scene::IAnimatedMesh*) scm_to_pointer (mesh),
44                                     (TParent) scm_to_pointer (parent),
45                                     scm_to_int32 (id),
46                                     scm_to_vector3df (position),
47                                     scm_to_vector3df (rotation),
48                                     scm_to_vector3df (scale),
49                                     scm_to_bool (also_add_if_mesh_pointer_zero));
50   return scm_from_pointer ((void*) node, NULL);
51 }
52
53 template <typename TParent>
54 SCM
55 ISceneManager_addCameraSceneNode (SCM scene_manager,
56                                   SCM parent,
57                                   SCM position,
58                                   SCM lookat,
59                                   SCM id,
60                                   SCM make_active)
61 {
62   scene::ISceneManager* smgr = (scene::ISceneManager*) scm_to_pointer (scene_manager);
63   scene::ICameraSceneNode* camera =
64     smgr->addCameraSceneNode ((TParent) scm_to_pointer (parent),
65                               scm_to_vector3df (position),
66                               scm_to_vector3df (lookat),
67                               scm_to_int32 (id),
68                               scm_to_bool (make_active));
69   return scm_from_pointer ((void*) camera, NULL);
70 }
71
72 template <typename TParent>
73 SCM
74 ISceneManager_addCameraSceneNodeFPS (SCM scene_manager,
75                                      SCM rest)
76 {
77   SCM parent;
78   SCM rotate_speed;
79   SCM move_speed;
80   SCM id;
81   SCM key_map_array;
82   SCM key_map_size;
83   SCM no_vertical_movement;
84   SCM jump_speed;
85   SCM invert_mouse;
86   SCM make_active;
87
88   scm_c_bind_keyword_arguments ("scene_ISceneManager_addCameraSceneNodeFPS",
89                                 rest, (scm_t_keyword_arguments_flags)0,
90                                 scm_from_utf8_keyword ("parent"), &parent,
91                                 scm_from_utf8_keyword ("rotate-speed"), &rotate_speed,
92                                 scm_from_utf8_keyword ("move-speed"), &move_speed,
93                                 scm_from_utf8_keyword ("id"), &id,
94                                 scm_from_utf8_keyword ("key-map-array"), &key_map_array,
95                                 scm_from_utf8_keyword ("key-map-size"), &key_map_size,
96                                 scm_from_utf8_keyword ("no-vertical-movement"), &no_vertical_movement,
97                                 scm_from_utf8_keyword ("jump-speed"), &jump_speed,
98                                 scm_from_utf8_keyword ("invert-mouse"), &invert_mouse,
99                                 scm_from_utf8_keyword ("make-active"), &make_active,
100                                 SCM_UNDEFINED);
101
102   scene::ISceneManager* smgr = (scene::ISceneManager*) scm_to_pointer (scene_manager);
103   scene::ICameraSceneNode* camera =
104     smgr->addCameraSceneNodeFPS ((TParent) scm_to_pointer (parent),
105                                  scm_to_double (rotate_speed),
106                                  scm_to_double (move_speed),
107                                  scm_to_int32 (id),
108                                  (SKeyMap*) scm_to_pointer (key_map_array),
109                                  scm_to_int32 (key_map_size),
110                                  scm_to_bool (no_vertical_movement),
111                                  scm_to_double (jump_speed),
112                                  scm_to_bool (invert_mouse),
113                                  scm_to_bool (make_active));
114   return scm_from_pointer ((void*) camera, NULL);
115 }
116
117 template <typename TParent>
118 SCM
119 ISceneManager_addCubeSceneNode (SCM scene_manager,
120                                 SCM size,
121                                 SCM parent,
122                                 SCM id,
123                                 SCM position,
124                                 SCM rotation,
125                                 SCM scale)
126 {
127   scene::ISceneManager* smgr = (scene::ISceneManager*) scm_to_pointer (scene_manager);
128   scene::IMeshSceneNode* node =
129     smgr->addCubeSceneNode (scm_to_double (size),
130                             (TParent) scm_to_pointer (parent),
131                             scm_to_int32 (id),
132                             scm_to_vector3df (position),
133                             scm_to_vector3df (rotation),
134                             scm_to_vector3df (scale));
135   return scm_from_pointer ((void*) node, NULL);
136 }
137
138 template <typename TParent>
139 SCM
140 ISceneManager_addCustomSceneNode (SCM scene_manager,
141                                   SCM proc_render,
142                                   SCM proc_get_bounding_box,
143                                   SCM proc_get_material_count,
144                                   SCM proc_get_material,
145                                   SCM parent,
146                                   SCM id,
147                                   SCM position,
148                                   SCM rotation,
149                                   SCM scale)
150 {
151   class CustomSceneNode : public scene::ISceneNode
152   {
153     SCM scm_render;
154     SCM scm_get_bounding_box;
155     SCM scm_get_material_count;
156     SCM scm_get_material;
157
158   public:
159     CustomSceneNode (scene::ISceneNode* parent,
160                      scene::ISceneManager* smgr,
161                      s32 id,
162                      const core::vector3df& position,
163                      const core::vector3df& rotation,
164                      const core::vector3df& scale,
165                      SCM render,
166                      SCM get_bounding_box,
167                      SCM get_material_count,
168                      SCM get_material)
169       : scene::ISceneNode (parent, smgr, id, position, rotation, scale)
170     {
171       scm_render = render;
172       scm_get_bounding_box = get_bounding_box;
173       scm_get_material_count = get_material_count;
174       scm_get_material = get_material;
175     }
176
177     virtual void OnRegisterSceneNode ()
178     {
179       if (IsVisible)
180         {
181           SceneManager->registerNodeForRendering (this);
182         }
183       ISceneNode::OnRegisterSceneNode ();
184     }
185
186     virtual void render ()
187     {
188       scm_call_0 (scm_render);
189     }
190
191     virtual const core::aabbox3d<f32>& getBoundingBox () const
192     {
193       SCM box = scm_call_0 (scm_get_bounding_box);
194       return *((core::aabbox3d<f32>*) scm_to_pointer (box));
195     }
196
197     virtual u32 getMaterialCount () const
198     {
199       return scm_to_uint32 (scm_call_0 (scm_get_material_count));
200     }
201
202     virtual video::SMaterial& getMaterial (u32 i)
203     {
204       SCM material = scm_call_1 (scm_get_material, scm_from_uint32 (i));
205       return *((video::SMaterial*) scm_to_pointer (material));
206     }
207   };
208
209   CustomSceneNode* node =
210     new CustomSceneNode ((TParent) scm_to_pointer (parent),
211                          (scene::ISceneManager*) scm_to_pointer (scene_manager),
212                          scm_to_int32 (id),
213                          scm_to_vector3df (position),
214                          scm_to_vector3df (rotation),
215                          scm_to_vector3df (scale),
216                          proc_render,
217                          proc_get_bounding_box,
218                          proc_get_material_count,
219                          proc_get_material);
220   return scm_from_pointer ((void*) node, NULL);
221 }
222
223 template <typename TParent, typename TMesh>
224 SCM
225 ISceneManager_addOctreeSceneNode (SCM scene_manager,
226                                   SCM mesh,
227                                   SCM parent,
228                                   SCM id,
229                                   SCM minimal_polys_per_node,
230                                   SCM also_add_if_mesh_pointer_zero)
231 {
232   scene::ISceneManager* smgr = (scene::ISceneManager*) scm_to_pointer (scene_manager);
233   scene::IMeshSceneNode* node =
234     smgr->addOctreeSceneNode ((TMesh) scm_to_pointer (mesh),
235                               (TParent) scm_to_pointer (parent),
236                               scm_to_int32 (id),
237                               scm_to_int32 (minimal_polys_per_node),
238                               scm_to_bool (also_add_if_mesh_pointer_zero));
239   return scm_from_pointer ((void*) node, NULL);
240 }
241
242 template <typename TParent>
243 SCM
244 ISceneManager_addSphereSceneNode (SCM scene_manager,
245                                   SCM radius,
246                                   SCM poly_count,
247                                   SCM parent,
248                                   SCM id,
249                                   SCM position,
250                                   SCM rotation,
251                                   SCM scale)
252 {
253   scene::ISceneManager* smgr = (scene::ISceneManager*) scm_to_pointer (scene_manager);
254   scene::IMeshSceneNode* node =
255     smgr->addSphereSceneNode (scm_to_double (radius),
256                               scm_to_int32 (poly_count),
257                               (TParent) scm_to_pointer (parent),
258                               scm_to_int32 (id),
259                               scm_to_vector3df (position),
260                               scm_to_vector3df (rotation),
261                               scm_to_vector3df (scale));
262   return scm_from_pointer ((void*) node, NULL);
263 }
264
265 SCM
266 ISceneManager_createFlyCircleAnimator (SCM scene_manager,
267                                        SCM center,
268                                        SCM radius,
269                                        SCM speed,
270                                        SCM direction,
271                                        SCM start_position,
272                                        SCM radius_ellipsoid)
273 {
274   scene::ISceneManager* smgr = (scene::ISceneManager*) scm_to_pointer (scene_manager);
275   scene::ISceneNodeAnimator* anim =
276     smgr->createFlyCircleAnimator (scm_to_vector3df (center),
277                                    scm_to_double (radius),
278                                    scm_to_double (speed),
279                                    scm_to_vector3df (direction),
280                                    scm_to_double (start_position),
281                                    scm_to_double (radius_ellipsoid));
282   return scm_from_pointer ((void*) anim, NULL);
283 }
284
285 SCM
286 ISceneManager_createFlyStraightAnimator (SCM scene_manager,
287                                          SCM start_point,
288                                          SCM end_point,
289                                          SCM time_for_way,
290                                          SCM loop,
291                                          SCM pingpong)
292 {
293   scene::ISceneManager* smgr = (scene::ISceneManager*) scm_to_pointer (scene_manager);
294   scene::ISceneNodeAnimator* anim =
295     smgr->createFlyStraightAnimator (scm_to_vector3df (start_point),
296                                      scm_to_vector3df (end_point),
297                                      scm_to_uint32 (time_for_way),
298                                      scm_to_bool (loop),
299                                      scm_to_bool (pingpong));
300   return scm_from_pointer ((void*) anim, NULL);
301 }
302
303 SCM
304 ISceneManager_createRotationAnimator (SCM scene_manager,
305                                       SCM rotation_speed)
306 {
307   scene::ISceneManager* smgr = (scene::ISceneManager*) scm_to_pointer (scene_manager);
308   scene::ISceneNodeAnimator* anim =
309     smgr->createRotationAnimator (scm_to_vector3df (rotation_speed));
310   return scm_from_pointer ((void*) anim, NULL);
311 }
312
313 SCM
314 ISceneManager_drawAll (SCM scene_manager)
315 {
316   ((scene::ISceneManager*) scm_to_pointer (scene_manager))->drawAll ();
317   return SCM_UNSPECIFIED;
318 }
319
320 SCM
321 ISceneManager_getMesh (SCM scene_manager,
322                        SCM filename)
323 {
324   scene::ISceneManager* smgr = (scene::ISceneManager*) scm_to_pointer (scene_manager);
325   scene::IAnimatedMesh* mesh = smgr->getMesh(scm_to_utf8_stringn (filename, NULL));
326   return scm_from_pointer ((void*) mesh, NULL);
327 }
328
329 SCM
330 ISceneManager_getRootSceneNode (SCM scene_manager)
331 {
332   scene::ISceneManager* smgr = (scene::ISceneManager*) scm_to_pointer (scene_manager);
333   return scm_from_pointer ((void*) smgr->getRootSceneNode (), NULL);
334 }
335
336 void
337 init_scene_manager (void)
338 {
339   DEFINE_GSUBR ("ISceneManager_addAnimatedMeshSceneNode_ISceneNode", 8, 0, 0,
340                 ISceneManager_addAnimatedMeshSceneNode<scene::ISceneNode*>);
341   DEFINE_GSUBR ("ISceneManager_addCameraSceneNode_ISceneNode", 6, 0, 0,
342                 ISceneManager_addCameraSceneNode<scene::ISceneNode*>);
343   DEFINE_GSUBR ("ISceneManager_addCameraSceneNodeFPS_ISceneNode", 1, 0, 1,
344                 ISceneManager_addCameraSceneNodeFPS<scene::ISceneNode*>);
345   DEFINE_GSUBR ("ISceneManager_addCubeSceneNode_ISceneNode", 7, 0, 0,
346                 ISceneManager_addCubeSceneNode<scene::ISceneNode*>);
347   DEFINE_GSUBR ("ISceneManager_addCustomSceneNode_ISceneNode", 10, 0, 0,
348                 ISceneManager_addCustomSceneNode<scene::ISceneNode*>);
349   DEFINE_GSUBR ("ISceneManager_addOctreeSceneNode_ISceneNode_IAnimatedMesh", 6, 0, 0,
350                 (ISceneManager_addOctreeSceneNode<scene::ISceneNode*, scene::IAnimatedMesh*>));
351   DEFINE_GSUBR ("ISceneManager_addOctreeSceneNode_ISceneNode_IMesh", 6, 0, 0,
352                 (ISceneManager_addOctreeSceneNode<scene::ISceneNode*, scene::IMesh*>));
353   DEFINE_GSUBR ("ISceneManager_addSphereSceneNode_ISceneNode", 8, 0, 0,
354                 ISceneManager_addSphereSceneNode<scene::ISceneNode*>);
355   DEFINE_GSUBR ("ISceneManager_createFlyCircleAnimator", 7, 0, 0,
356                 ISceneManager_createFlyCircleAnimator);
357   DEFINE_GSUBR ("ISceneManager_createFlyStraightAnimator", 6, 0, 0,
358                 ISceneManager_createFlyStraightAnimator);
359   DEFINE_GSUBR ("ISceneManager_createRotationAnimator", 2, 0, 0,
360                 ISceneManager_createRotationAnimator);
361   DEFINE_GSUBR ("ISceneManager_drawAll", 1, 0, 0, ISceneManager_drawAll);
362   DEFINE_GSUBR ("ISceneManager_getMesh", 2, 0, 0, ISceneManager_getMesh);
363   DEFINE_GSUBR ("ISceneManager_getRootSceneNode", 1, 0, 0, ISceneManager_getRootSceneNode);
364 }