commit ae496eb2b7cccfac69d6a0f2ceadb00cef0227e8
parent 968f6f8b78c22e07e5cecf08fedb43ba8a9f0600
Author: Christophe Coustet <christophe.coustet@meso-star.com>
Date: Wed, 29 Jun 2016 17:00:27 +0200
First try to scene.
Diffstat:
5 files changed, 322 insertions(+), 0 deletions(-)
diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt
@@ -52,6 +52,7 @@ set(SSOL_FILES_SRC
ssol_material.c
ssol_object.c
ssol_object_instance.c
+ ssol_scene.c
ssol_shape.c)
set(SSOL_FILES_INC_API
@@ -63,6 +64,7 @@ set(SSOL_FILES_INC
ssol_material_c.h
ssol_object_c.h
ssol_object_instance_c.h
+ ssol_scene_c.h
ssol_shape_c.h)
set(SSOL_FILES_DOC COPYING README.md)
@@ -117,6 +119,7 @@ if(NOT NO_TEST)
new_test(test_ssol_material)
new_test(test_ssol_object)
new_test(test_ssol_object_instance)
+ new_test(test_ssol_scene)
new_test(test_ssol_shape)
endif(NOT NO_TEST)
diff --git a/src/ssol.h b/src/ssol.h
@@ -285,6 +285,12 @@ ssol_scene_detach_object_instance
(struct ssol_scene* scn,
struct ssol_object_instance* instance);
+/* Detach all the instances from the scene and release the reference that the
+* scene takes onto them */
+SSOL_API res_T
+ssol_scene_clear
+ (struct ssol_scene* scn);
+
SSOL_API res_T
ssol_scene_attach_sun
(struct ssol_scene* scn,
@@ -411,6 +417,11 @@ ssol_object_instance_set_receiver_image
struct ssol_image* image,
const enum ssol_parametrization_type type);
+SSOL_API res_T
+ssol_object_instance_is_attached
+ (struct ssol_object_instance* instance,
+ char* is_attached);
+
/*******************************************************************************
* Spectrum API - Collection of wavelengths with their associated data.
******************************************************************************/
diff --git a/src/ssol_scene.c b/src/ssol_scene.c
@@ -0,0 +1,177 @@
+/* Copyright (C) CNRS 2016
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#include "ssol.h"
+#include "ssol_scene_c.h"
+#include "ssol_device_c.h"
+#include "ssol_object_instance_c.h"
+
+#include <rsys\rsys.h>
+#include <rsys\mem_allocator.h>
+#include <rsys\ref_count.h>
+
+/*******************************************************************************
+* Helper functions
+******************************************************************************/
+
+static void
+scene_release(ref_T* ref)
+{
+ struct ssol_scene* scene;
+ struct ssol_device* dev;
+ ASSERT(ref);
+ scene = CONTAINER_OF(ref, struct ssol_scene, ref);
+ SSOL(scene_clear(scene));
+ dev = scene->dev;
+ ASSERT(dev && dev->allocator);
+ SSOL(scene_clear(scene));
+ if (scene->scene3D) s3d_scene_ref_put(scene->scene3D);
+ MEM_RM(dev->allocator, scene);
+ SSOL(device_ref_put(dev));
+}
+
+static void
+scene_detach_instance
+ (struct ssol_scene* scene,
+ struct ssol_object_instance* instance)
+{
+ ASSERT(scene && instance && !is_list_empty(&instance->scene_attachment));
+ ASSERT(scene->instances_count != 0);
+
+ list_del(&instance->scene_attachment);
+ --scene->instances_count;
+ SSOL(object_instance_ref_put(instance));
+}
+
+/*******************************************************************************
+* Local functions
+******************************************************************************/
+
+/*******************************************************************************
+* Exported ssol_image functions
+******************************************************************************/
+
+res_T
+ssol_scene_create
+ (struct ssol_device* dev,
+ struct ssol_scene** out_scene)
+{
+ struct ssol_scene* scene = NULL;
+ res_T res = RES_OK;
+ if (!dev || !out_scene) {
+ return RES_BAD_ARG;
+ }
+
+ scene = (struct ssol_scene*)MEM_CALLOC
+ (dev->allocator, 1, sizeof(struct ssol_scene));
+ if (!scene) {
+ res = RES_MEM_ERR;
+ goto error;
+ }
+ list_init(&scene->instances);
+ SSOL(device_ref_get(dev));
+ scene->dev = dev;
+ ref_init(&scene->ref);
+
+exit:
+ if (out_scene) *out_scene = scene;
+ return res;
+error:
+ if (scene) {
+ SSOL(scene_ref_put(scene));
+ scene = NULL;
+ }
+ goto exit;
+}
+
+res_T
+ssol_scene_ref_get
+ (struct ssol_scene* scene)
+{
+ if (!scene)
+ return RES_BAD_ARG;
+ ref_get(&scene->ref);
+ return RES_OK;
+}
+
+res_T
+ssol_scene_ref_put
+ (struct ssol_scene* scene)
+{
+ if (!scene)
+ return RES_BAD_ARG;
+ ref_put(&scene->ref, scene_release);
+ return RES_OK;
+}
+
+res_T
+ssol_scene_attach_object_instance
+ (struct ssol_scene* scene,
+ struct ssol_object_instance* instance)
+{
+ if (!scene || !instance)
+ return RES_BAD_ARG;
+ if (!is_list_empty(&instance->scene_attachment))
+ return RES_BAD_ARG;
+
+ /* instance is chained into the list of instance of the scene */
+ list_add_tail(&scene->instances, &instance->scene_attachment);
+ SSOL(object_instance_ref_get(instance));
+ scene->instances_count++;
+ return RES_OK;
+}
+
+res_T
+ssol_scene_detach_object_instance
+ (struct ssol_scene* scene,
+ struct ssol_object_instance* instance)
+{
+ char is_attached;
+ if (!scene || !instance) return RES_BAD_ARG;
+ if (!(SSOL(object_instance_is_attached(instance, &is_attached)), is_attached))
+ return RES_BAD_ARG;
+
+#ifndef NDEBUG
+ { /* Check that instance is attached to `scene' */
+ struct list_node* node;
+ char is_found = 0;
+ LIST_FOR_EACH(node, &scene->instances) {
+ if (node == &instance->scene_attachment) {
+ is_found = 1;
+ break;
+ }
+ }
+ ASSERT(is_found);
+ }
+#endif
+
+ scene_detach_instance(scene, instance);
+ return RES_OK;
+}
+
+res_T
+ssol_scene_clear
+ (struct ssol_scene* scene)
+{
+ struct list_node* node, *tmp;
+ if (!scene) return RES_BAD_ARG;
+
+ LIST_FOR_EACH_SAFE(node, tmp, &scene->instances) {
+ struct ssol_object_instance* instance = CONTAINER_OF
+ (node, struct ssol_object_instance, scene_attachment);
+ scene_detach_instance(scene, instance);
+ }
+ return RES_OK;
+}
+\ No newline at end of file
diff --git a/src/ssol_scene_c.h b/src/ssol_scene_c.h
@@ -0,0 +1,31 @@
+/* Copyright (C) CNRS 2016
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#ifndef SSOL_SCENE_C_H
+#define SSOL_SCENE_C_H
+
+#include <rsys/ref_count.h>
+#include <rsys/list.h>
+
+struct ssol_scene {
+ struct list_node instances; /* List of attached instances */
+ size_t instances_count;
+ struct s3d_scene* scene3D;
+
+ struct ssol_device* dev;
+ ref_T ref;
+};
+
+#endif /* SSOL_SCENE_C_H */
diff --git a/src/test_ssol_scene.c b/src/test_ssol_scene.c
@@ -0,0 +1,98 @@
+/* Copyright (C) CNRS 2016
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#include "ssol.h"
+#include "test_ssol_utils.h"
+
+#include <rsys/logger.h>
+
+/*******************************************************************************
+* test main program
+******************************************************************************/
+int
+main(int argc, char** argv)
+{
+ struct logger logger;
+ struct mem_allocator allocator;
+ struct ssol_device* dev;
+ struct ssol_carving carving;
+ struct ssol_quadric quadric;
+ struct ssol_shape* shape;
+ struct ssol_punched_surface punched_surface;
+ struct ssol_material* material;
+ struct ssol_object* object;
+ struct ssol_object_instance* instance;
+ struct ssol_scene* scene;
+ double transform[12];
+ (void) argc, (void) argv;
+
+ mem_init_proxy_allocator(&allocator, &mem_default_allocator);
+
+ CHECK(logger_init(&allocator, &logger), RES_OK);
+ logger_set_stream(&logger, LOG_OUTPUT, log_stream, NULL);
+ logger_set_stream(&logger, LOG_ERROR, log_stream, NULL);
+ logger_set_stream(&logger, LOG_WARNING, log_stream, NULL);
+
+ CHECK(ssol_device_create(&logger, &allocator, SSOL_NTHREADS_DEFAULT, 0, &dev), RES_OK);
+
+ CHECK(ssol_material_create_virtual(dev, &material), RES_OK);
+
+ carving.type = SSOL_CARVING_CIRCLE;
+ carving.internal = 0;
+ carving.data.circle.center[0] = 0;
+ carving.data.circle.center[1] = 0;
+ carving.data.circle.radius = 1;
+ quadric.type = SSOL_QUADRIC_PLANE;
+ punched_surface.nb_carvings = 1;
+ punched_surface.quadric = &quadric;
+ punched_surface.carvings = &carving;
+ CHECK(ssol_shape_create_punched_surface(dev, &shape), RES_OK);
+ CHECK(ssol_object_create(dev, shape, material, &object), RES_OK);
+ CHECK(ssol_object_instantiate(object, &instance), RES_OK);
+ CHECK(ssol_object_instance_set_transform(instance, transform), RES_OK);
+
+ CHECK(ssol_scene_create(dev, &scene), RES_OK);
+
+ CHECK(ssol_scene_ref_get(NULL), RES_BAD_ARG);
+ CHECK(ssol_scene_ref_get(scene), RES_OK);
+
+ CHECK(ssol_scene_ref_put(NULL), RES_BAD_ARG);
+ CHECK(ssol_scene_ref_put(scene), RES_OK);
+
+ CHECK(ssol_scene_attach_object_instance(NULL, instance), RES_BAD_ARG);
+ CHECK(ssol_scene_attach_object_instance(scene, NULL), RES_BAD_ARG);
+ CHECK(ssol_scene_attach_object_instance(scene, instance), RES_OK);
+
+ CHECK(ssol_scene_detach_object_instance(NULL, instance), RES_BAD_ARG);
+ CHECK(ssol_scene_detach_object_instance(scene, NULL), RES_BAD_ARG);
+ CHECK(ssol_scene_detach_object_instance(scene, instance), RES_OK);
+
+ CHECK(ssol_scene_ref_put(scene), RES_OK);
+
+ CHECK(ssol_object_instance_ref_put(instance), RES_OK);
+ CHECK(ssol_object_ref_put(object), RES_OK);
+ CHECK(ssol_shape_ref_put(shape), RES_OK);
+ CHECK(ssol_material_ref_put(material), RES_OK);
+
+ CHECK(ssol_device_ref_put(dev), RES_OK);
+
+ logger_release(&logger);
+
+ check_memory_allocator(&allocator);
+ mem_shutdown_proxy_allocator(&allocator);
+ CHECK(mem_allocated_size(), 0);
+
+ return 0;
+}
+\ No newline at end of file