1 /* guile-irrlicht --- GNU Guile bindings for Irrlicht Engine
3 Copyright (C) 2020 Javier Sancho <jsf@jsancho.org>
5 This file is part of guile-irrlicht.
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.
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.
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/>.
22 #include <irrlicht/irrlicht.h>
25 #include "animated-mesh.h"
26 #include "animated-mesh-scene-node.h"
28 #include "camera-scene-node.h"
34 #include "mesh-scene-node.h"
35 #include "scene-manager.h"
36 #include "scene-node.h"
37 #include "scene-node-animator.h"
42 irr_drawAll (SCM wrapped_obj)
44 if (gui_environment_p (wrapped_obj))
46 unwrap_gui_environment (wrapped_obj)->drawAll ();
48 else if (scene_manager_p (wrapped_obj))
50 unwrap_scene_manager (wrapped_obj)->drawAll ();
54 scm_error (scm_arg_type_key, NULL, "Cannot draw all elements from object: ~S",
55 scm_list_1 (wrapped_obj), scm_list_1 (wrapped_obj));
57 return SCM_UNSPECIFIED;
63 init_scene_manager (void)
65 init_scene_manager_type ();
66 DEFINE_GSUBR ("add-animated-mesh-scene-node!", 2, 0, 1, irr_scene_addAnimatedMeshSceneNode);
67 DEFINE_GSUBR ("add-camera-scene-node!", 1, 0, 1, irr_scene_addCameraSceneNode);
68 DEFINE_GSUBR ("add-camera-scene-node-fps!", 1, 0, 1, irr_scene_addCameraSceneNodeFPS);
69 DEFINE_GSUBR ("add-cube-scene-node!", 1, 0, 1, irr_scene_addCubeSceneNode);
70 DEFINE_GSUBR ("add-custom-scene-node!", 5, 0, 1, irr_scene_addCustomSceneNode);
71 DEFINE_GSUBR ("add-octree-scene-node!", 2, 0, 1, irr_scene_addOctreeSceneNode);
72 DEFINE_GSUBR ("add-sphere-scene-node!", 1, 0, 1, irr_scene_addSphereSceneNode);
73 DEFINE_GSUBR ("create-fly-circle-animator", 1, 0, 1, irr_scene_createFlyCircleAnimator);
74 DEFINE_GSUBR ("create-fly-straight-animator", 4, 0, 1, irr_scene_createFlyStraightAnimator);
75 DEFINE_GSUBR ("create-rotation-animator", 2, 0, 0, irr_scene_createRotationAnimator);
76 DEFINE_GSUBR ("get-mesh", 2, 0, 0, irr_scene_getMesh);
77 DEFINE_GSUBR ("get-root-scene-node", 1, 0, 0, irr_scene_getRootSceneNode);
80 DEFINE_WRAPPED_TYPE (irr::scene::ISceneManager*, "scene-manager",
81 init_scene_manager_type, scene_manager_p,
82 wrap_scene_manager, unwrap_scene_manager);
85 irr_scene_addAnimatedMeshSceneNode (SCM wrapped_scene_manager,
89 SCM parent = SCM_UNDEFINED;
90 SCM id = scm_from_int32 (-1);
91 SCM position = scm_list_3 (scm_from_double (0),
94 SCM rotation = scm_list_3 (scm_from_double (0),
97 SCM scale = scm_list_3 (scm_from_double (1),
100 SCM also_add_if_mesh_pointer_zero = SCM_BOOL_F;
102 scm_c_bind_keyword_arguments ("add-animated-mesh-scene-node!", rest, (scm_t_keyword_arguments_flags)0,
103 scm_from_utf8_keyword ("parent"), &parent,
104 scm_from_utf8_keyword ("id"), &id,
105 scm_from_utf8_keyword ("position"), &position,
106 scm_from_utf8_keyword ("rotation"), &rotation,
107 scm_from_utf8_keyword ("scale"), &scale,
108 scm_from_utf8_keyword ("also-add-if-mesh-pointer-zero"), &also_add_if_mesh_pointer_zero,
111 irr::scene::ISceneManager* smgr = unwrap_scene_manager (wrapped_scene_manager);
112 irr::scene::IAnimatedMeshSceneNode* node =
113 smgr->addAnimatedMeshSceneNode (unwrap_animated_mesh (mesh),
114 parent == SCM_UNDEFINED ? 0 : unwrap_scene_node (parent),
116 scm_to_vector3df (position),
117 scm_to_vector3df (rotation),
118 scm_to_vector3df (scale),
119 scm_to_bool (also_add_if_mesh_pointer_zero));
120 return wrap_animated_mesh_scene_node (node);
124 irr_scene_addCameraSceneNode (SCM wrapped_scene_manager,
127 SCM parent = SCM_UNDEFINED;
128 SCM position = scm_list_3 (scm_from_double (0),
130 scm_from_double (0));
131 SCM lookat = scm_list_3 (scm_from_double (0),
133 scm_from_double (100));
134 SCM id = scm_from_int32 (-1);
135 SCM make_active = SCM_BOOL_T;
137 scm_c_bind_keyword_arguments ("add-camera-scene-node!", rest, (scm_t_keyword_arguments_flags)0,
138 scm_from_utf8_keyword ("parent"), &parent,
139 scm_from_utf8_keyword ("position"), &position,
140 scm_from_utf8_keyword ("lookat"), &lookat,
141 scm_from_utf8_keyword ("id"), &id,
142 scm_from_utf8_keyword ("make-active"), &make_active,
145 irr::scene::ISceneManager* scene_manager = unwrap_scene_manager (wrapped_scene_manager);
146 irr::scene::ICameraSceneNode* camera =
147 scene_manager->addCameraSceneNode (parent == SCM_UNDEFINED ? 0 : unwrap_scene_node (parent),
148 scm_to_vector3df (position),
149 scm_to_vector3df (lookat),
151 scm_to_bool (make_active));
152 return wrap_camera_scene_node (camera);
156 irr_scene_addCameraSceneNodeFPS (SCM wrapped_scene_manager,
159 SCM parent = SCM_UNDEFINED;
160 SCM rotate_speed = scm_from_double (100);
161 SCM move_speed = scm_from_double (0.5);
162 SCM id = scm_from_int32 (-1);
163 SCM key_map_array = SCM_UNDEFINED;
164 SCM key_map_size = scm_from_int32 (0);
165 SCM no_vertical_movement = SCM_BOOL_F;
166 SCM jump_speed = scm_from_double (0);
167 SCM invert_mouse = SCM_BOOL_F;
168 SCM make_active = SCM_BOOL_T;
170 scm_c_bind_keyword_arguments ("add-camera-scene-node-fps!", rest, (scm_t_keyword_arguments_flags)0,
171 scm_from_utf8_keyword ("parent"), &parent,
172 scm_from_utf8_keyword ("rotate-speed"), &rotate_speed,
173 scm_from_utf8_keyword ("move-speed"), &move_speed,
174 scm_from_utf8_keyword ("id"), &id,
175 scm_from_utf8_keyword ("key-map-array"), &key_map_array,
176 scm_from_utf8_keyword ("key-map-size"), &key_map_size,
177 scm_from_utf8_keyword ("no-vertical-movement"), &no_vertical_movement,
178 scm_from_utf8_keyword ("jump-speed"), &jump_speed,
179 scm_from_utf8_keyword ("invert-mouse"), &invert_mouse,
180 scm_from_utf8_keyword ("make-active"), &make_active,
183 irr::scene::ISceneManager* scene_manager = unwrap_scene_manager (wrapped_scene_manager);
184 irr::scene::ICameraSceneNode* camera =
185 scene_manager->addCameraSceneNodeFPS (parent == SCM_UNDEFINED ? 0 : unwrap_scene_node (parent),
186 scm_to_double (rotate_speed),
187 scm_to_double (move_speed),
189 key_map_array == SCM_UNDEFINED ? 0 : unwrap_keymap (key_map_array),
190 scm_to_int32 (key_map_size),
191 scm_to_bool (no_vertical_movement),
192 scm_to_double (jump_speed),
193 scm_to_bool (invert_mouse),
194 scm_to_bool (make_active));
195 return wrap_camera_scene_node (camera);
199 irr_scene_addCubeSceneNode (SCM wrapped_scene_manager,
202 SCM size = scm_from_double (10);
203 SCM parent = SCM_UNDEFINED;
204 SCM id = scm_from_int32 (-1);
205 SCM position = scm_list_3 (scm_from_double (0),
207 scm_from_double (0));
208 SCM rotation = scm_list_3 (scm_from_double (0),
210 scm_from_double (0));
211 SCM scale = scm_list_3 (scm_from_double (1),
213 scm_from_double (1));
215 scm_c_bind_keyword_arguments ("add-cube-scene-node!", rest, (scm_t_keyword_arguments_flags)0,
216 scm_from_utf8_keyword ("size"), &size,
217 scm_from_utf8_keyword ("parent"), &parent,
218 scm_from_utf8_keyword ("id"), &id,
219 scm_from_utf8_keyword ("position"), &position,
220 scm_from_utf8_keyword ("rotation"), &rotation,
221 scm_from_utf8_keyword ("scale"), &scale,
224 irr::scene::ISceneManager* smgr = unwrap_scene_manager (wrapped_scene_manager);
225 irr::scene::IMeshSceneNode* node =
226 smgr->addCubeSceneNode (scm_to_double (size),
227 parent == SCM_UNDEFINED ? 0 : unwrap_scene_node (parent),
229 scm_to_vector3df (position),
230 scm_to_vector3df (rotation),
231 scm_to_vector3df (scale));
232 return wrap_mesh_scene_node (node);
236 irr_scene_addCustomSceneNode (SCM wrapped_scene_manager,
238 SCM proc_get_bounding_box,
239 SCM proc_get_material_count,
240 SCM proc_get_material,
243 irr::scene::ISceneManager* scene_manager = unwrap_scene_manager (wrapped_scene_manager);
245 SCM parent = wrap_scene_node (scene_manager->getRootSceneNode ());
246 SCM id = scm_from_int32 (-1);
247 SCM position = scm_list_3 (scm_from_double (0),
249 scm_from_double (0));
250 SCM rotation = scm_list_3 (scm_from_double (0),
252 scm_from_double (0));
253 SCM scale = scm_list_3 (scm_from_double (1),
255 scm_from_double (1));
257 scm_c_bind_keyword_arguments ("add-custom-scene-node!", rest, (scm_t_keyword_arguments_flags)0,
258 scm_from_utf8_keyword ("parent"), &parent,
259 scm_from_utf8_keyword ("id"), &id,
260 scm_from_utf8_keyword ("position"), &position,
261 scm_from_utf8_keyword ("rotation"), &rotation,
262 scm_from_utf8_keyword ("scale"), &scale,
265 class CustomSceneNode : public irr::scene::ISceneNode
268 SCM scm_get_bounding_box;
269 SCM scm_get_material_count;
270 SCM scm_get_material;
273 CustomSceneNode (irr::scene::ISceneNode* parent,
274 irr::scene::ISceneManager* smgr,
276 const irr::core::vector3df& position,
277 const irr::core::vector3df& rotation,
278 const irr::core::vector3df& scale,
280 SCM get_bounding_box,
281 SCM get_material_count,
283 : irr::scene::ISceneNode (parent, smgr, id, position, rotation, scale)
286 scm_get_bounding_box = get_bounding_box;
287 scm_get_material_count = get_material_count;
288 scm_get_material = get_material;
291 virtual void OnRegisterSceneNode ()
295 SceneManager->registerNodeForRendering (this);
297 ISceneNode::OnRegisterSceneNode ();
300 virtual void render ()
302 scm_call_0 (scm_render);
305 virtual const irr::core::aabbox3d<irr::f32>& getBoundingBox () const
307 SCM box = scm_call_0 (scm_get_bounding_box);
308 return *(unwrap_box3d (box));
311 virtual irr::u32 getMaterialCount () const
313 return scm_to_uint32 (scm_call_0 (scm_get_material_count));
316 virtual irr::video::SMaterial& getMaterial (irr::u32 i)
318 SCM material = scm_call_1 (scm_get_material, scm_from_uint32 (i));
319 return *(unwrap_material (material));
323 CustomSceneNode* node =
324 new CustomSceneNode (unwrap_scene_node (parent),
327 scm_to_vector3df (position),
328 scm_to_vector3df (rotation),
329 scm_to_vector3df (scale),
331 proc_get_bounding_box,
332 proc_get_material_count,
334 return wrap_scene_node (node);
338 irr_scene_addOctreeSceneNode (SCM wrapped_scene_manager,
342 SCM parent = SCM_UNDEFINED;
343 SCM id = scm_from_int32 (-1);
344 SCM minimal_polys_per_node = scm_from_int32 (256);
345 SCM also_add_if_mesh_pointer_zero = SCM_BOOL_F;
347 scm_c_bind_keyword_arguments ("add-octree-scene-node!", rest, (scm_t_keyword_arguments_flags)0,
348 scm_from_utf8_keyword ("parent"), &parent,
349 scm_from_utf8_keyword ("id"), &id,
350 scm_from_utf8_keyword ("minimal-polys-per-node"), &minimal_polys_per_node,
351 scm_from_utf8_keyword ("also-add-if-mesh-pointer-zero"), &also_add_if_mesh_pointer_zero,
354 irr::scene::ISceneManager* smgr = unwrap_scene_manager (wrapped_scene_manager);
355 irr::scene::IMeshSceneNode* node;
356 if (animated_mesh_p (wrapped_mesh))
358 node = smgr->addOctreeSceneNode (unwrap_animated_mesh (wrapped_mesh),
359 parent == SCM_UNDEFINED ? 0 : unwrap_scene_node (parent),
361 scm_to_int32 (minimal_polys_per_node),
362 scm_to_bool (also_add_if_mesh_pointer_zero));
366 node = smgr->addOctreeSceneNode (unwrap_mesh (wrapped_mesh),
367 parent == SCM_UNDEFINED ? 0 : unwrap_scene_node (parent),
369 scm_to_int32 (minimal_polys_per_node),
370 scm_to_bool (also_add_if_mesh_pointer_zero));
372 return wrap_mesh_scene_node (node);
376 irr_scene_addSphereSceneNode (SCM wrapped_scene_manager,
379 SCM radius = scm_from_double (5.0);
380 SCM poly_count = scm_from_int32 (16);
381 SCM parent = SCM_UNDEFINED;
382 SCM id = scm_from_int32 (-1);
383 SCM position = scm_list_3 (scm_from_double (0),
385 scm_from_double (0));
386 SCM rotation = scm_list_3 (scm_from_double (0),
388 scm_from_double (0));
389 SCM scale = scm_list_3 (scm_from_double (1),
391 scm_from_double (1));
393 scm_c_bind_keyword_arguments ("add-sphere-scene-node!", rest, (scm_t_keyword_arguments_flags)0,
394 scm_from_utf8_keyword ("radius"), &radius,
395 scm_from_utf8_keyword ("poly-count"), &poly_count,
396 scm_from_utf8_keyword ("parent"), &parent,
397 scm_from_utf8_keyword ("id"), &id,
398 scm_from_utf8_keyword ("position"), &position,
399 scm_from_utf8_keyword ("rotation"), &rotation,
400 scm_from_utf8_keyword ("scale"), &scale,
403 irr::scene::ISceneManager* smgr = unwrap_scene_manager (wrapped_scene_manager);
404 irr::scene::IMeshSceneNode* node =
405 smgr->addSphereSceneNode (scm_to_double (radius),
406 scm_to_int32 (poly_count),
407 parent == SCM_UNDEFINED ? 0 : unwrap_scene_node (parent),
409 scm_to_vector3df (position),
410 scm_to_vector3df (rotation),
411 scm_to_vector3df (scale));
412 return wrap_mesh_scene_node (node);
416 irr_scene_createFlyCircleAnimator (SCM wrapped_scene_manager,
419 SCM center = scm_list_3 (scm_from_double (0),
421 scm_from_double (0));
422 SCM radius = scm_from_double (100);
423 SCM speed = scm_from_double (0.001);
424 SCM direction = scm_list_3 (scm_from_double (0),
426 scm_from_double (0));
427 SCM start_position = scm_from_double (0);
428 SCM radius_ellipsoid = scm_from_double (0);
430 scm_c_bind_keyword_arguments ("create-fly-circle-animator", rest, (scm_t_keyword_arguments_flags)0,
431 scm_from_utf8_keyword ("center"), ¢er,
432 scm_from_utf8_keyword ("radius"), &radius,
433 scm_from_utf8_keyword ("speed"), &speed,
434 scm_from_utf8_keyword ("direction"), &direction,
435 scm_from_utf8_keyword ("start-position"), &start_position,
436 scm_from_utf8_keyword ("radius-ellipsoid"), &radius_ellipsoid,
439 irr::scene::ISceneManager* smgr = unwrap_scene_manager (wrapped_scene_manager);
440 irr::scene::ISceneNodeAnimator* anim =
441 smgr->createFlyCircleAnimator (scm_to_vector3df (center),
442 scm_to_double (radius),
443 scm_to_double (speed),
444 scm_to_vector3df (direction),
445 scm_to_double (start_position),
446 scm_to_double (radius_ellipsoid));
447 return wrap_scene_node_animator (anim);
451 irr_scene_createFlyStraightAnimator (SCM wrapped_scene_manager,
457 SCM loop = SCM_BOOL_F;
458 SCM pingpong = SCM_BOOL_F;
460 scm_c_bind_keyword_arguments ("create-fly-straight-animator", rest, (scm_t_keyword_arguments_flags)0,
461 scm_from_utf8_keyword ("loop"), &loop,
462 scm_from_utf8_keyword ("pingpong"), &pingpong,
465 irr::scene::ISceneManager* smgr = unwrap_scene_manager (wrapped_scene_manager);
466 irr::scene::ISceneNodeAnimator* anim =
467 smgr->createFlyStraightAnimator (scm_to_vector3df (start_point),
468 scm_to_vector3df (end_point),
469 scm_to_uint32 (time_for_way),
471 scm_to_bool (pingpong));
472 return wrap_scene_node_animator (anim);
476 irr_scene_createRotationAnimator (SCM wrapped_scene_manager,
479 irr::scene::ISceneManager* smgr = unwrap_scene_manager (wrapped_scene_manager);
480 irr::scene::ISceneNodeAnimator* anim =
481 smgr->createRotationAnimator (scm_to_vector3df (rotation_speed));
482 return wrap_scene_node_animator (anim);
486 irr_scene_getMesh (SCM wrapped_scene_manager,
489 irr::scene::ISceneManager* smgr = unwrap_scene_manager (wrapped_scene_manager);
490 irr::scene::IAnimatedMesh* mesh = smgr->getMesh(scm_to_utf8_stringn (filename, NULL));
491 return wrap_animated_mesh (mesh);
495 irr_scene_getRootSceneNode (SCM wrapped_scene_manager)
497 irr::scene::ISceneManager* smgr = unwrap_scene_manager (wrapped_scene_manager);
498 return wrap_scene_node (smgr->getRootSceneNode ());