solstice-solver

Solver library of the solstice app
git clone git://git.meso-star.com/solstice-solver.git
Log | Files | Refs | README | LICENSE

commit cfeb38895a8d20f44378ebd7ffd70219c02ec1bd
parent 67a225f5693979547da10f56587412c51dde5ab4
Author: Christophe Coustet <christophe.coustet@meso-star.com>
Date:   Fri, 24 Jun 2016 18:34:11 +0200

Add missing files.

Diffstat:
Asrc/ssol_shape.c | 288+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/ssol_shape_c.h | 50++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/test_ssol_shape.c | 158+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 496 insertions(+), 0 deletions(-)

diff --git a/src/ssol_shape.c b/src/ssol_shape.c @@ -0,0 +1,287 @@ +/* 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_shape_c.h" +#include "ssol_device_c.h" + +#include <rsys\rsys.h> +#include <rsys\mem_allocator.h> +#include <rsys\ref_count.h> + +/******************************************************************************* +* Helper functions +******************************************************************************/ + +static void +shape_mesh_release(ref_T* ref) +{ + struct shape_mesh* mesh; + ASSERT(ref); + + mesh = CONTAINER_OF(ref, struct shape_mesh, ref); + if (mesh->shape) S3D(shape_ref_put(mesh->shape)); + ASSERT(mesh->dev && mesh->dev->allocator); + MEM_RM(mesh->dev->allocator, mesh); + SSOL(device_ref_put(mesh->dev)); +} + +static void +shape_mesh_ref_get(struct shape_mesh* mesh) +{ + ASSERT(mesh); + ref_get(&mesh->ref); +} + +static void +shape_mesh_ref_put(struct shape_mesh* mesh) +{ + ASSERT(mesh); + ref_put(&mesh->ref, shape_mesh_release); +} + +static void +shape_release(ref_T* ref) +{ + struct ssol_shape* shape; + ASSERT(ref); + shape = CONTAINER_OF(ref, struct ssol_shape, ref); + + switch (shape->type) { + case SHAPE_NONE: + break; + case SHAPE_MESH: + if (shape->data.mesh) shape_mesh_ref_put(shape->data.mesh); + break; + case SHAPE_PUNCHED: + if (shape->data.punched) /* TODO */; + break; + default: FATAL("Unreachable code \n"); break; + } + + ASSERT(shape->dev); + MEM_RM(shape->dev->allocator, shape); + SSOL(device_ref_put(shape->dev)); +} + +/******************************************************************************* +* Local functions +******************************************************************************/ + +static res_T +shape_create(struct ssol_device* dev, struct ssol_shape** out_shape) +{ + struct ssol_shape* shape = NULL; + res_T res = RES_OK; + + ASSERT(dev && out_shape); + + shape = (struct ssol_shape*)MEM_CALLOC + (dev->allocator, 1, sizeof(struct ssol_shape)); + if (!shape) { + res = RES_MEM_ERR; + goto error; + } + + SSOL(device_ref_get(dev)); + shape->dev = dev; + ref_init(&shape->ref); + shape->type = SHAPE_NONE; + +exit: + if (out_shape) *out_shape = shape; + return res; +error: + if (shape) { + SSOL(shape_ref_put(shape)); + shape = NULL; + } + goto exit; + +} + +static res_T +shape_mesh_create +(struct ssol_device* dev, + struct shape_mesh** out_mesh) +{ + struct shape_mesh* mesh = NULL; + res_T res = RES_OK; + + mesh = (struct shape_mesh*)MEM_CALLOC + (dev->allocator, 1, sizeof(struct shape_mesh)); + if (!mesh) { + res = RES_MEM_ERR; + goto error; + } + + res = s3d_shape_create_mesh(dev->s3d, &mesh->shape); + if (res != RES_OK) + goto error; + + SSOL(device_ref_get(dev)); + mesh->dev = dev; + ref_init(&mesh->ref); + +exit: + if (out_mesh) *out_mesh = mesh; + return res; +error: + if (mesh) { + shape_mesh_ref_put(mesh); + mesh = NULL; + } + goto exit; +} + +/******************************************************************************* +* Exported ssol_shape functions +******************************************************************************/ + +res_T +ssol_shape_create_mesh + (struct ssol_device* dev, + struct ssol_shape** out_shape) +{ + struct ssol_shape* shape = NULL; + res_T res = RES_OK; + + if (!dev || !out_shape) { + res = RES_BAD_ARG; + goto error; + } + + res = shape_create(dev, &shape); + if (res != RES_OK) + goto error; + + res = shape_mesh_create(dev, &shape->data.mesh); + if (res != RES_OK) + goto error; + + shape->type = SHAPE_MESH; + shape->dev = dev; + ref_init(&shape->ref); + +exit: + if (out_shape) *out_shape = shape; + return res; +error: + if (shape) { + SSOL(shape_ref_put(shape)); + shape = NULL; + } + goto exit; +} + +res_T +ssol_shape_create_punched_surface + (struct ssol_device* dev, + struct ssol_shape** out_shape) +{ + res_T res = RES_OK; + + if (!dev || !out_shape) { + return RES_BAD_ARG; + } + + return res; +} + +res_T +ssol_shape_ref_get +(struct ssol_shape* shape) +{ + if (!shape) return RES_BAD_ARG; + ref_get(&shape->ref); + return RES_OK; +} + +res_T +ssol_shape_ref_put +(struct ssol_shape* shape) +{ + if (!shape) return RES_BAD_ARG; + ref_put(&shape->ref, shape_release); + return RES_OK; +} + +res_T +ssol_punched_surface_setup + (struct ssol_shape* shape, + const struct ssol_punched_surface* punched_surface) +{ + res_T res = RES_OK; + + if (!shape || shape->type != SHAPE_PUNCHED || !punched_surface) { + return RES_BAD_ARG; + } + + return res; +} + +res_T +ssol_mesh_setup + (struct ssol_shape* shape, + const unsigned ntris, + void(*get_indices)(const unsigned itri, unsigned ids[3], void* ctx), + const unsigned nverts, + const struct ssol_vertex_data attribs [], + const unsigned nattribs, + void* data) +{ + struct s3d_vertex_data* _attrib3 = NULL; + res_T res = RES_OK; + unsigned i; + + if (!shape || shape->type != SHAPE_MESH || !get_indices) { + return RES_BAD_ARG; + } + if (!ntris || !nverts || !attribs || !nattribs) { + return RES_BAD_ARG; + } + ASSERT(shape->ref); + ASSERT(shape->dev && shape->dev->allocator && shape->data.mesh); + + _attrib3 = (struct s3d_vertex_data*)MEM_CALLOC + (shape->dev->allocator, nattribs, sizeof(struct s3d_vertex_data)); + if (!_attrib3) { + return RES_MEM_ERR; + } + + for (i = 0; i < nattribs; i++) { + _attrib3[i].get = attribs[i].get; + switch (attribs[i].usage) { + case SSOL_POSITION: + _attrib3[i].usage = S3D_POSITION; + _attrib3[i].type = S3D_FLOAT3; + break; + case SSOL_NORMAL: + _attrib3[i].usage = S3D_GEOMETRY_NORMAL; + _attrib3[i].type = S3D_FLOAT3; + break; + case SSOL_TEXCOORD: + _attrib3[i].usage = S3D_ATTRIB_0; + _attrib3[i].type = S3D_FLOAT2; + break; + default: + FATAL("Unreachable code \n"); + break; + } + } + res = s3d_mesh_setup_indexed_vertices(shape->data.mesh->shape, ntris, get_indices, nverts, _attrib3, nattribs, data); + MEM_RM(shape->dev->allocator, _attrib3); + return res; +} +\ No newline at end of file diff --git a/src/ssol_shape_c.h b/src/ssol_shape_c.h @@ -0,0 +1,50 @@ +/* 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_SHAPE_C_H +#define SSOL_SHAPE_C_H + +#include <rsys/ref_count.h> + +enum shape_type { + SHAPE_NONE, + SHAPE_MESH, + SHAPE_PUNCHED +}; + +struct shape_mesh { + struct s3d_shape* shape; + + struct ssol_device* dev; + ref_T ref; +}; + +struct shape_punched { + char TODO; +}; + +struct ssol_shape { + enum shape_type type; + + union { + struct shape_mesh* mesh; + struct shape_punched* punched; + } data; + + struct ssol_device* dev; + ref_T ref; +}; + +#endif /* SSOL_SHAPE_C_H */ diff --git a/src/test_ssol_shape.c b/src/test_ssol_shape.c @@ -0,0 +1,157 @@ +/* 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> + +static void +log_stream(const char* msg, void* ctx) +{ + ASSERT(msg); + (void) msg, (void) ctx; + printf("%s\n", msg); +} + +/******************************************************************************* +* Box +******************************************************************************/ +struct cbox_desc { + const float* vertices; + const unsigned* indices; +}; + +static const float cbox_walls [] = { + 552.f, 0.f, 0.f, + 0.f, 0.f, 0.f, + 0.f, 559.f, 0.f, + 552.f, 559.f, 0.f, + 552.f, 0.f, 548.f, + 0.f, 0.f, 548.f, + 0.f, 559.f, 548.f, + 552.f, 559.f, 548.f +}; +const unsigned cbox_walls_nverts = sizeof(cbox_walls) / sizeof(float[3]); + +const unsigned cbox_walls_ids [] = { + 0, 1, 2, 2, 3, 0, /* Bottom */ + 4, 5, 6, 6, 7, 4, /* Top */ + 1, 2, 6, 6, 5, 1, /* Left */ + 0, 3, 7, 7, 4, 0, /* Right */ + 2, 3, 7, 7, 6, 2 /* Back */ +}; +const unsigned cbox_walls_ntris = sizeof(cbox_walls_ids) / sizeof(unsigned[3]); + +static const struct cbox_desc cbox_walls_desc = { cbox_walls, cbox_walls_ids }; + +/******************************************************************************* +* Callbacks +******************************************************************************/ +static INLINE void +cbox_get_ids(const unsigned itri, unsigned ids[3], void* data) +{ + const unsigned id = itri * 3; + struct cbox_desc* desc = data; + NCHECK(desc, NULL); + ids[0] = desc->indices[id + 0]; + ids[1] = desc->indices[id + 1]; + ids[2] = desc->indices[id + 2]; +} + +static INLINE void +cbox_get_position(const unsigned ivert, float position[3], void* data) +{ + struct cbox_desc* desc = data; + NCHECK(desc, NULL); + position[0] = desc->vertices[ivert * 3 + 0]; + position[1] = desc->vertices[ivert * 3 + 1]; + position[2] = desc->vertices[ivert * 3 + 2]; +} + +static INLINE void +cbox_get_normal(const unsigned ivert, float normal[3], void* data) +{ + (void) ivert, (void) data; + normal[0] = 1.f; + normal[1] = 0.f; + normal[2] = 0.f; +} + +static INLINE void +cbox_get_uv(const unsigned ivert, float uv[2], void* data) +{ + (void) ivert, (void) data; + uv[0] = -1.f; + uv[1] = 1.f; +} + +int +main(int argc, char** argv) +{ + struct logger logger; + struct mem_allocator allocator; + struct ssol_device* dev; + struct ssol_shape* shape; + struct ssol_vertex_data attribs[3]; + void* data = (void*) &cbox_walls_desc; + (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_shape_create_mesh(NULL, NULL), RES_BAD_ARG); + CHECK(ssol_shape_create_mesh(dev, NULL), RES_BAD_ARG); + CHECK(ssol_shape_create_mesh(NULL, &shape), RES_BAD_ARG); + CHECK(ssol_shape_create_mesh(dev, &shape), RES_OK); + + CHECK(ssol_shape_ref_get(NULL), RES_BAD_ARG); + CHECK(ssol_shape_ref_get(shape), RES_OK); + + CHECK(ssol_shape_ref_put(NULL), RES_BAD_ARG); + CHECK(ssol_shape_ref_put(shape), RES_OK); + + attribs[0].usage = SSOL_POSITION; + attribs[0].get = cbox_get_position; + attribs[1].usage = SSOL_NORMAL; + attribs[1].get = cbox_get_normal; + attribs[2].usage = SSOL_TEXCOORD; + attribs[2].get = cbox_get_uv; + + CHECK(ssol_mesh_setup(NULL, cbox_walls_ntris, cbox_get_ids, cbox_walls_nverts, attribs, 1, data), RES_BAD_ARG); + CHECK(ssol_mesh_setup(shape, 0, cbox_get_ids, cbox_walls_nverts, attribs, 1, data), RES_BAD_ARG); + CHECK(ssol_mesh_setup(shape, cbox_walls_ntris, NULL, cbox_walls_nverts, attribs, 1, data), RES_BAD_ARG); + CHECK(ssol_mesh_setup(shape, cbox_walls_ntris, cbox_get_ids, 0, attribs, 1, data), RES_BAD_ARG); + CHECK(ssol_mesh_setup(shape, cbox_walls_ntris, cbox_get_ids, cbox_walls_nverts, NULL, 1, data), RES_BAD_ARG); + CHECK(ssol_mesh_setup(shape, cbox_walls_ntris, cbox_get_ids, cbox_walls_nverts, attribs, 0, data), RES_BAD_ARG); + CHECK(ssol_mesh_setup(shape, cbox_walls_ntris, cbox_get_ids, cbox_walls_nverts, attribs, 3, data), RES_OK); + + CHECK(ssol_shape_ref_put(shape), 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