commit d42657c6b741ad830e634d8f752ca7c2cfff6244
parent fd3f022892f49353b2cc04755d66e5f18a8c1f38
Author: Christophe Coustet <christophe.coustet@meso-star.com>
Date: Thu, 26 Jan 2017 18:35:41 +0100
Two axis pivots.
Diffstat:
9 files changed, 627 insertions(+), 49 deletions(-)
diff --git a/doc/input b/doc/input
@@ -113,6 +113,12 @@
# normal: <real3>
# <target>
#
+# <pivot2> ::=
+# pivot2:
+# spacing: REAL # in [0, INF)
+# ref_point: <real3>
+# <target>
+#
# <target> ::=
# target:
# anchor: <anchor-identifier>
@@ -217,7 +223,7 @@
#
# <entity-data> ::=
# name: STRING
-# [ <geometry-data> | <pivot> ]
+# [ <geometry-data> | <pivot> | <pivot2> ]
# [ <anchors> ]
# [ <transform> ]
# [ <children> ]
@@ -293,3 +299,4 @@
# <spectrum-data> ::=
# wavelength: REAL # in [0, INF)
# data: REAL # in [0, INF)
+#
+\ No newline at end of file
diff --git a/src/parser/solparser.c b/src/parser/solparser.c
@@ -151,6 +151,12 @@ struct target_alias {
#define DARRAY_FUNCTOR_INIT solparser_pivot_init
#include <rsys/dynamic_array.h>
+/* Declare the array of pivot2s */
+#define DARRAY_NAME pivot2
+#define DARRAY_DATA struct solparser_pivot2
+#define DARRAY_FUNCTOR_INIT solparser_pivot2_init
+#include <rsys/dynamic_array.h>
+
/* Declare the hash table that maps the address of a YAML node to the id of its
* in memory representation. */
#define HTABLE_NAME yaml2sols
@@ -201,6 +207,7 @@ struct solparser {
/* Miscellaneous */
struct darray_anchor anchors;
struct darray_pivot pivots;
+ struct darray_pivot2 pivot2s;
ref_T ref;
struct mem_allocator* allocator;
@@ -229,6 +236,13 @@ parse_pivot
struct solparser_pivot_id* out_isolpivot);
static res_T
+parse_pivot2
+ (struct solparser* parser,
+ yaml_document_t* doc,
+ const yaml_node_t* pivot2,
+ struct solparser_pivot_id* out_isolpivot);
+
+static res_T
parse_sun
(struct solparser* parser,
yaml_document_t* doc,
@@ -331,10 +345,10 @@ flush_deferred_target_aliases
/* Define the targeted anchor of the pivot */
pivot = darray_pivot_data_get(&parser->pivots) + tgt->pivot.i;
- ASSERT(pivot->target_type == SOLPARSER_TARGET_ANCHOR);
+ ASSERT(pivot->target.type == SOLPARSER_TARGET_ANCHOR);
ianchor = (size_t)(anchor - darray_anchor_cdata_get(&parser->anchors));
ASSERT(ianchor < darray_anchor_size_get(&parser->anchors));
- pivot->target.anchor.i = ianchor;
+ pivot->target.data.anchor.i = ianchor;
}
darray_tgtalias_clear(&parser->tgtaliases);
@@ -390,6 +404,7 @@ parser_clear(struct solparser* parser)
/* Miscellaneous */
darray_anchor_clear(&parser->anchors);
darray_pivot_clear(&parser->pivots);
+ darray_pivot2_clear(&parser->pivot2s);
}
static void
@@ -439,6 +454,7 @@ parser_release(ref_T* ref)
/* Miscellaneous */
darray_anchor_release(&parser->anchors);
darray_pivot_release(&parser->pivots);
+ darray_pivot2_release(&parser->pivot2s);
MEM_RM(parser->allocator, parser);
}
@@ -2527,6 +2543,11 @@ parse_entity
SETUP_MASK(DATA, "data");
solent.type = SOLPARSER_ENTITY_PIVOT;
res = parse_pivot(parser, doc, val, &solent.data.pivot);
+ }
+ else if (!strcmp((char*) key->data.scalar.value, "pivot2")) {
+ SETUP_MASK(DATA, "data");
+ solent.type = SOLPARSER_ENTITY_PIVOT2;
+ res = parse_pivot2(parser, doc, val, &solent.data.pivot2);
} else if(!strcmp((char*)key->data.scalar.value, "transform")) {
SETUP_MASK(TRANSFORM, "transform");
res = parse_transform
@@ -2652,35 +2673,32 @@ error:
}
static res_T
-parse_target
+parse_target_
(struct solparser* parser,
yaml_document_t* doc,
- const yaml_node_t* target,
- struct solparser_pivot* pivot)
+ const yaml_node_t* target_node,
+ struct solparser_target* target,
+ struct solparser_pivot_id pivot_id)
{
enum { POLICY };
intptr_t i, n;
int mask = 0; /* Register the parsed attributes */
- struct solparser_pivot_id pivot_id;
res_T res = RES_OK;
- ASSERT(doc && target && pivot);
+ ASSERT(doc && target_node && target);
- if(target->type != YAML_MAPPING_NODE) {
- log_err(parser, target, "expect a target definition.\n");
+ if(target_node->type != YAML_MAPPING_NODE) {
+ log_err(parser, target_node, "expect a target definition.\n");
res = RES_BAD_ARG;
goto error;
}
- /* Retrieve the pivot id */
- pivot_id.i = (size_t)(pivot - darray_pivot_cdata_get(&parser->pivots));
-
- n = target->data.mapping.pairs.top - target->data.mapping.pairs.start;
+ n = target_node->data.mapping.pairs.top - target_node->data.mapping.pairs.start;
FOR_EACH(i, 0, n) {
yaml_node_t* key;
yaml_node_t* val;
- key = yaml_document_get_node(doc, target->data.mapping.pairs.start[i].key);
- val = yaml_document_get_node(doc, target->data.mapping.pairs.start[i].value);
+ key = yaml_document_get_node(doc, target_node->data.mapping.pairs.start[i].key);
+ val = yaml_document_get_node(doc, target_node->data.mapping.pairs.start[i].value);
if(key->type != YAML_SCALAR_NODE) {
log_err(parser, key, "expect a target parameter.\n");
res = RES_BAD_ARG;
@@ -2697,18 +2715,18 @@ parse_target
} (void)0
if(!strcmp((char*)key->data.scalar.value, "anchor")) {
SETUP_MASK(POLICY, "policy");
- pivot->target_type = SOLPARSER_TARGET_ANCHOR;
- res = parse_anchor_alias(parser, val, pivot_id, &pivot->target.anchor);
+ target->type = SOLPARSER_TARGET_ANCHOR;
+ res = parse_anchor_alias(parser, val, pivot_id, &target->data.anchor);
} else if(!strcmp((char*)key->data.scalar.value, "direction")) {
SETUP_MASK(POLICY, "policy");
- pivot->target_type = SOLPARSER_TARGET_DIRECTION;
+ target->type = SOLPARSER_TARGET_DIRECTION;
res = parse_real3
- (parser, doc, val, -DBL_MAX, DBL_MAX, pivot->target.direction);
+ (parser, doc, val, -DBL_MAX, DBL_MAX, target->data.direction);
} else if(!strcmp((char*)key->data.scalar.value, "position")) {
SETUP_MASK(POLICY, "policy");
- pivot->target_type = SOLPARSER_TARGET_POSITION;
+ target->type = SOLPARSER_TARGET_POSITION;
res = parse_real3
- (parser, doc, val, -DBL_MAX, DBL_MAX, pivot->target.position);
+ (parser, doc, val, -DBL_MAX, DBL_MAX, target->data.position);
} else if(!strcmp((char*)key->data.scalar.value, "sun")) {
/* There is only one sun per YAML file. It is thus sufficient to define
* the target_type to SOLPARSER_TARGET_SUN to indentify which data is
@@ -2716,7 +2734,7 @@ parse_target
* to target */
struct solparser_sun* sun;
SETUP_MASK(POLICY, "policy");
- pivot->target_type = SOLPARSER_TARGET_SUN;
+ target->type = SOLPARSER_TARGET_SUN;
res = parse_sun(parser, doc, val, &sun);
} else {
log_err(parser, key, "unknown target parameter `%s'.\n",
@@ -2732,7 +2750,100 @@ parse_target
}
if(!(mask & BIT(POLICY))) {
- log_err(parser, target, "the target policy is missing.\n");
+ log_err(parser, target_node, "the target policy is missing.\n");
+ res = RES_BAD_ARG;
+ goto error;
+ }
+
+exit:
+ return res;
+error:
+ goto exit;
+}
+
+static res_T
+parse_target
+ (struct solparser* parser,
+ yaml_document_t* doc,
+ const yaml_node_t* target_node,
+ const struct solparser_pivot_id pivot_id,
+ struct solparser_target* target)
+{
+ enum { POLICY };
+ intptr_t i, n;
+ int mask = 0; /* Register the parsed attributes */
+ res_T res = RES_OK;
+ ASSERT(doc && target_node && target);
+
+ if (target_node->type != YAML_MAPPING_NODE) {
+ log_err(parser, target_node, "expect a target definition.\n");
+ res = RES_BAD_ARG;
+ goto error;
+ }
+
+ n = target_node->data.mapping.pairs.top - target_node->data.mapping.pairs.start;
+ FOR_EACH(i, 0, n) {
+ yaml_node_t* key;
+ yaml_node_t* val;
+
+ key = yaml_document_get_node(doc, target_node->data.mapping.pairs.start[i].key);
+ val = yaml_document_get_node(doc, target_node->data.mapping.pairs.start[i].value);
+ if (key->type != YAML_SCALAR_NODE) {
+ log_err(parser, key, "expect a target parameter.\n");
+ res = RES_BAD_ARG;
+ goto error;
+ }
+
+#define SETUP_MASK(Flag, Name) { \
+ if(mask & BIT(Flag)) { \
+ log_err(parser, key, "the target "Name" is already defined.\n"); \
+ res = RES_BAD_ARG; \
+ goto error; \
+ } \
+ mask |= BIT(Flag); \
+ } (void)0
+ if (!strcmp((char*) key->data.scalar.value, "anchor")) {
+ SETUP_MASK(POLICY, "policy");
+ target->type = SOLPARSER_TARGET_ANCHOR;
+ res = parse_anchor_alias(parser, val, pivot_id, &target->data.anchor);
+ }
+ else if (!strcmp((char*) key->data.scalar.value, "direction")) {
+ SETUP_MASK(POLICY, "policy");
+ target->type = SOLPARSER_TARGET_DIRECTION;
+ res = parse_real3
+ (parser, doc, val, -DBL_MAX, DBL_MAX, target->data.direction);
+ }
+ else if (!strcmp((char*) key->data.scalar.value, "position")) {
+ SETUP_MASK(POLICY, "policy");
+ target->type = SOLPARSER_TARGET_POSITION;
+ res = parse_real3
+ (parser, doc, val, -DBL_MAX, DBL_MAX, target->data.position);
+ }
+ else if (!strcmp((char*) key->data.scalar.value, "sun")) {
+ /* There is only one sun per YAML file. It is thus sufficient to define
+ * the target_type to SOLPARSER_TARGET_SUN to indentify which data is
+ * targeted, i.e. it is not necessary to store the identifier of the sun
+ * to target */
+ struct solparser_sun* sun;
+ SETUP_MASK(POLICY, "policy");
+ target->type = SOLPARSER_TARGET_SUN;
+ res = parse_sun(parser, doc, val, &sun);
+ }
+ else {
+ log_err(parser, key, "unknown target parameter `%s'.\n",
+ key->data.scalar.value);
+ res = RES_BAD_ARG;
+ goto error;
+ }
+ if (res != RES_OK) {
+ log_node(parser, key);
+ goto error;
+ }
+#undef SETUP_MASK
+ }
+
+ if (!(mask & BIT(POLICY))) {
+ log_err(parser, target_node, "the target policy is missing.\n");
res = RES_BAD_ARG;
goto error;
}
@@ -2802,8 +2913,10 @@ parse_pivot
SETUP_MASK(NORMAL, "normal");
res = parse_real3(parser, doc, val, -DBL_MAX, DBL_MAX, solpivot->normal);
} else if(!strcmp((char*)key->data.scalar.value, "target")) {
+ struct solparser_pivot_id pivot_id;
+ pivot_id.i = (size_t) (solpivot - darray_pivot_cdata_get(&parser->pivots));
SETUP_MASK(TARGET, "target");
- res = parse_target(parser, doc, val, solpivot);
+ res = parse_target(parser, doc, val, pivot_id, &solpivot->target);
} else {
log_err(parser, key, "unknown pivot parameter `%s'.\n",
key->data.scalar.value);
@@ -2838,6 +2951,106 @@ error:
goto exit;
}
+static res_T
+parse_pivot2
+ (struct solparser* parser,
+ yaml_document_t* doc,
+ const yaml_node_t* pivot2,
+ struct solparser_pivot_id* out_isolpivot)
+{
+ enum { SPACING, REF_POINT, TARGET };
+ struct solparser_pivot2* solpivot2 = NULL;
+ size_t isolpivot = SIZE_MAX;
+ int mask = 0; /* Register the parsed attributes */
+ intptr_t i, n;
+ res_T res = RES_OK;
+ ASSERT(doc && pivot2 && out_isolpivot);
+
+ if (pivot2->type != YAML_MAPPING_NODE) {
+ log_err(parser, pivot2, "expect a pivot2 definition.\n");
+ res = RES_BAD_ARG;
+ goto error;
+ }
+
+ /* Allocate the solstice pivot */
+ isolpivot = darray_pivot2_size_get(&parser->pivot2s);
+ res = darray_pivot2_resize(&parser->pivot2s, isolpivot + 1);
+ if (res != RES_OK) {
+ log_err(parser, pivot2, "could not allocate the pivot2.\n");
+ res = RES_BAD_ARG;
+ goto error;
+ }
+ solpivot2 = darray_pivot2_data_get(&parser->pivot2s) + isolpivot;
+
+ n = pivot2->data.mapping.pairs.top - pivot2->data.mapping.pairs.start;
+ FOR_EACH(i, 0, n) {
+ yaml_node_t* key;
+ yaml_node_t* val;
+
+ key = yaml_document_get_node(doc, pivot2->data.mapping.pairs.start[i].key);
+ val = yaml_document_get_node(doc, pivot2->data.mapping.pairs.start[i].value);
+ if (key->type != YAML_SCALAR_NODE) {
+ log_err(parser, key, "expect pivot2 parameters.\n");
+ res = RES_BAD_ARG;
+ goto error;
+ }
+#define SETUP_MASK(Flag, Name) { \
+ if(mask & BIT(Flag)) { \
+ log_err(parser, key, \
+ "the pivot2 parameter `"Name"' is already defined.\n"); \
+ res = RES_BAD_ARG; \
+ goto error; \
+ } \
+ mask |= BIT(Flag); \
+ } (void)0
+ if (!strcmp((char*) key->data.scalar.value, "spacing")) {
+ SETUP_MASK(SPACING, "spacing");
+ res = parse_real(parser, val, 0, DBL_MAX, &solpivot2->spacing);
+ }
+ else if (!strcmp((char*) key->data.scalar.value, "ref_point")) {
+ SETUP_MASK(REF_POINT, "ref_point");
+ res = parse_real3(parser, doc, val, -DBL_MAX, DBL_MAX, solpivot2->ref_point);
+ }
+ else if (!strcmp((char*) key->data.scalar.value, "target")) {
+ struct solparser_pivot_id pivot_id;
+ pivot_id.i = (size_t) (solpivot2 - darray_pivot2_cdata_get(&parser->pivot2s));
+ SETUP_MASK(TARGET, "target");
+ res = parse_target(parser, doc, val, pivot_id, &solpivot2->target);
+ }
+ else {
+ log_err(parser, key, "unknown pivot2 parameter `%s'.\n",
+ key->data.scalar.value);
+ res = RES_BAD_ARG;
+ goto error;
+ }
+ if (res != RES_OK) {
+ log_node(parser, key);
+ goto error;
+ }
+#undef SETUP_MASK
+ }
+#define CHECK_PARAM(Flag, Name) \
+ if(!(mask & BIT(Flag))) { \
+ log_err(parser, pivot2, "the pivot2 parameter `"Name"' is missing.\n");\
+ res = RES_BAD_ARG; \
+ goto error; \
+ } (void)0
+ CHECK_PARAM(SPACING, "spacing");
+ CHECK_PARAM(REF_POINT, "ref_point");
+ CHECK_PARAM(TARGET, "target");
+#undef CHECK_PARAM
+
+ exit :
+ out_isolpivot->i = isolpivot;
+ return res;
+ error:
+ if (solpivot2) {
+ darray_pivot2_pop_back(&parser->pivot2s);
+ isolpivot = SIZE_MAX;
+ }
+ goto exit;
+}
+
/*******************************************************************************
* Sun
******************************************************************************/
@@ -3206,9 +3419,10 @@ solparser_create
htable_str2sols_init(mem_allocator, &parser->str2entities);
darray_entity_init(mem_allocator, &parser->entities);
- /* Anchors */
+ /* Anchors and pivot(2)s */
darray_anchor_init(mem_allocator, &parser->anchors);
darray_pivot_init(mem_allocator, &parser->pivots);
+ darray_pivot2_init(mem_allocator, &parser->pivot2s);
exit:
*out_parser = parser;
@@ -3547,6 +3761,15 @@ solparser_get_pivot
return darray_pivot_cdata_get(&parser->pivots) + pivot.i;
}
+const struct solparser_pivot2*
+solparser_get_pivot2
+ (const struct solparser* parser,
+ const struct solparser_pivot_id pivot2)
+{
+ ASSERT(parser && pivot2.i < darray_pivot2_size_get(&parser->pivot2s));
+ return darray_pivot2_cdata_get(&parser->pivot2s) + pivot2.i;
+}
+
const struct solparser_shape*
solparser_get_shape
(const struct solparser* parser,
diff --git a/src/parser/solparser.h b/src/parser/solparser.h
@@ -122,6 +122,11 @@ solparser_get_pivot
(const struct solparser* parser,
const struct solparser_pivot_id pivot);
+extern LOCAL_SYM const struct solparser_pivot2*
+solparser_get_pivot2
+ (const struct solparser* parser,
+ const struct solparser_pivot_id pivot2);
+
extern LOCAL_SYM const struct solparser_shape*
solparser_get_shape
(const struct solparser* parser,
diff --git a/src/parser/solparser_entity.h b/src/parser/solparser_entity.h
@@ -29,7 +29,8 @@
enum solparser_entity_type {
SOLPARSER_ENTITY_EMPTY,
SOLPARSER_ENTITY_GEOMETRY,
- SOLPARSER_ENTITY_PIVOT
+ SOLPARSER_ENTITY_PIVOT,
+ SOLPARSER_ENTITY_PIVOT2
};
struct solparser_entity_id { size_t i; };
@@ -67,6 +68,7 @@ struct solparser_entity {
union {
struct solparser_geometry_id geometry;
struct solparser_pivot_id pivot;
+ struct solparser_pivot_id pivot2;
} data;
/* Internal data. Should not be acceded directly. */
diff --git a/src/parser/solparser_pivot.h b/src/parser/solparser_pivot.h
@@ -67,33 +67,57 @@ solparser_anchor_copy_and_release
return str_copy_and_release(&dst->name, &src->name);
}
-struct solparser_pivot {
- double point[3];
- double normal[3];
- enum solparser_target_type target_type;
+struct solparser_target {
+ enum solparser_target_type type;
union {
double position[3]; /* World space position */
double direction[3]; /* World space direction */
struct solparser_anchor_id anchor;
- } target;
+ } data;
+};
+
+struct solparser_pivot_id { size_t i; };
+
+struct solparser_pivot {
+ double point[3];
+ double normal[3];
+ struct solparser_target target;
};
#define SOLPARSER_PIVOT_NULL__ { \
{0,0,0}, {0,0,0}, SOLPARSER_TARGET_TYPES_COUNT__, {{0,0,0}} \
}
-static const struct solparser_pivot SOLPARSER_PIVOT_NULL =
- SOLPARSER_PIVOT_NULL__;
-
-struct solparser_pivot_id { size_t i; };
+static const struct solparser_pivot SOLPARSER_PIVOT_NULL =
+SOLPARSER_PIVOT_NULL__;
static INLINE void
solparser_pivot_init
- (struct mem_allocator* allocator, struct solparser_pivot* pivot)
+(struct mem_allocator* allocator, struct solparser_pivot* pivot)
{
(void) allocator;
ASSERT(pivot);
*pivot = SOLPARSER_PIVOT_NULL;
}
+struct solparser_pivot2 {
+ double spacing;
+ double ref_point[3];
+ struct solparser_target target;
+};
+
+#define SOLPARSER_PIVOT2_NULL__ { \
+ 0, {0,0,0}, SOLPARSER_TARGET_TYPES_COUNT__, {{0,0,0}} \
+}
+static const struct solparser_pivot2 SOLPARSER_PIVOT2_NULL =
+ SOLPARSER_PIVOT2_NULL__;
+
+static INLINE void
+solparser_pivot2_init
+ (struct mem_allocator* allocator, struct solparser_pivot2* pivot2)
+{
+ (void) allocator;
+ ASSERT(pivot2);
+ *pivot2 = SOLPARSER_PIVOT2_NULL;
+}
#endif /* SOLPARSER_PIVOT_H */
diff --git a/src/parser/test_solparser3.c b/src/parser/test_solparser3.c
@@ -52,6 +52,12 @@ static const char* input[] = {
" point: [1, 2, 3]\n",
" normal: [4, 5, 6]\n",
" target: { anchor: \"entity0.entity0b.anchor0\" }\n",
+ "- entity:\n",
+ " name: entity2\n",
+ " pivot2:\n",
+ " spacing: 1\n",
+ " ref_point: [1, 2, 3]\n",
+ " target: { anchor: \"entity0.entity0b.anchor0\" }\n",
NULL
};
@@ -61,6 +67,7 @@ const struct solparser_anchor* entity0_entity0b_anchor0;
const struct solparser_anchor* entity0_entity0b_entity0b;
const struct solparser_geometry* geom;
const struct solparser_pivot* pivot;
+const struct solparser_pivot2* pivot2;
static void
check_entity0
@@ -168,7 +175,27 @@ check_entity1
pivot = solparser_get_pivot(parser, entity1->data.pivot);
CHECK(d3_eq(pivot->point, d3(tmp, 1, 2, 3)), 1);
CHECK(d3_eq(pivot->normal, d3(tmp, 4, 5, 6)), 1);
- CHECK(pivot->target_type, SOLPARSER_TARGET_ANCHOR);
+ CHECK(pivot->target.type, SOLPARSER_TARGET_ANCHOR);
+}
+
+static void
+check_entity2
+(struct solparser* parser, const struct solparser_entity* entity2)
+{
+ double tmp[3];
+
+ NCHECK(parser, NULL);
+ NCHECK(entity2, NULL);
+
+ CHECK(strcmp(str_cget(&entity2->name), "entity2"), 0);
+ CHECK(entity2->type, SOLPARSER_ENTITY_PIVOT2);
+ CHECK(solparser_entity_get_anchors_count(entity2), 0);
+ CHECK(solparser_entity_get_children_count(entity2), 0);
+
+ pivot2 = solparser_get_pivot2(parser, entity2->data.pivot2);
+ CHECK(pivot2->spacing, 1);
+ CHECK(d3_eq(pivot2->ref_point, d3(tmp, 1, 2, 3)), 1);
+ CHECK(pivot2->target.type, SOLPARSER_TARGET_ANCHOR);
}
int
@@ -211,8 +238,12 @@ main(int argc, char** argv)
if(!strcmp(str_cget(&entity->name), "entity0")) {
check_entity0(parser, entity);
- } else if(!strcmp(str_cget(&entity->name), "entity1")) {
+ }
+ else if (!strcmp(str_cget(&entity->name), "entity1")) {
check_entity1(parser, entity);
+ }
+ else if(!strcmp(str_cget(&entity->name), "entity2")) {
+ check_entity2(parser, entity);
} else {
FATAL("Unexpected entity name.\n");
}
@@ -220,7 +251,7 @@ main(int argc, char** argv)
solparser_entity_iterator_next(&it);
}
- anchor = solparser_get_anchor(parser, pivot->target.anchor);
+ anchor = solparser_get_anchor(parser, pivot->target.data.anchor);
CHECK(anchor, entity0_entity0b_anchor0);
anchor = solparser_find_anchor(parser, "entity0");
diff --git a/src/parser/test_solparser5.c b/src/parser/test_solparser5.c
@@ -71,9 +71,9 @@ check_entity(struct solparser* parser, const struct solparser_entity* entity)
pivot = solparser_get_pivot(parser, entity->data.pivot);
CHECK(d3_eq(pivot->point, d3(tmp, 1, 2, 3)), 1);
CHECK(d3_eq(pivot->normal, d3(tmp, 4, 5, 6)), 1);
- CHECK(pivot->target_type, SOLPARSER_TARGET_ANCHOR);
+ CHECK(pivot->target.type, SOLPARSER_TARGET_ANCHOR);
- anchor = solparser_get_anchor(parser, pivot->target.anchor);
+ anchor = solparser_get_anchor(parser, pivot->target.data.anchor);
CHECK(strcmp(str_cget(&anchor->name), "anchor0"), 0);
CHECK(d3_eq(anchor->position, d3(tmp, 1, 2, 3)), 1);
}
diff --git a/src/parser/yaml/test_ko_0.yaml b/src/parser/yaml/test_ko_0.yaml
@@ -860,6 +860,179 @@
target: { sun: *sun }
---
+# <pivot2> ::=
+# pivot2:
+# spacing: REAL # in [0, INF)
+# ref_point: <real3>
+# <target>
+#
+# <target> ::=
+# target:
+# anchor: <anchor-identifier>
+# | direction: <real3>
+# | position: <real3>
+# | <sun>
+#
+
+# missing pivot2 definition
+- entity:
+ pivot2:
+---
+# unknown dummy parameter
+- entity:
+ pivot2:
+ dummy: 1
+---
+# missing spacing definition
+- entity:
+ pivot2:
+ spacing:
+---
+# missing ref_point definition
+- entity:
+ pivot2:
+ ref_point:
+---
+# missing target definition
+- entity:
+ pivot2:
+ target:
+---
+# spacing should be a number
+- entity:
+ pivot2:
+ spacing: "dummy"
+---
+# -1 invalid
+- entity:
+ pivot2:
+ spacing: -1
+---
+# spacing should be a number
+- entity:
+ pivot2:
+ ref_point: "dummy"
+---
+# ref_point should have 3 values
+- entity:
+ pivot2:
+ ref_point: [ -4, 5.2 ]
+---
+# ref_point should have 3 values
+- entity:
+ pivot2:
+ ref_point: [ -4, 5.2, 0, 1 ]
+---
+# target should be a <target>
+- entity:
+ pivot2:
+ target: "dummy"
+---
+# missing anchor definition
+- entity:
+ pivot2:
+ target:
+ anchor:
+---
+# missing direction definition
+- entity:
+ pivot2:
+ target:
+ direction:
+---
+# missing position definition
+- entity:
+ pivot2:
+ target:
+ position:
+---
+# undefined anchor
+- entity:
+ pivot2:
+ target:
+ anchor: dummy
+---
+# direction should be a number
+- entity:
+ pivot2:
+ target:
+ direction: "dummy"
+---
+# direction should have 3 values
+- entity:
+ pivot2:
+ target:
+ direction: [ -4, 5.2 ]
+---
+# direction should have 3 values
+- entity:
+ pivot2:
+ target:
+ direction: [ -4, 5.2, 0, 1 ]
+---
+# position should be a number
+- entity:
+ pivot2:
+ target:
+ position: "dummy"
+---
+# position should have 3 values
+- entity:
+ pivot2:
+ target:
+ position: [ -4, 5.2 ]
+---
+# position should have 3 values
+- entity:
+ pivot2:
+ target:
+ position: [ -4, 5.2, 0, 1 ]
+---
+# sun should be a <sun>
+- entity:
+ pivot2:
+ target: { sun: "dummy" }
+---
+# missing point
+- sun: &sun { dni: 1, spectrum: [{wavelength: 1, data: 1}] }
+- entity:
+ pivot2:
+ normal: [ -4, 5.2, 0 ]
+ target: { sun: *sun }
+---
+# missing normal
+- sun: &sun { dni: 1, spectrum: [{wavelength: 1, data: 1}] }
+- entity:
+ pivot2:
+ point: [ -4, 5.2, 0 ]
+ target: { sun: *sun }
+---
+# missing target
+- entity:
+ pivot2:
+ point: [ -4, 5.2, 0 ]
+ normal: [ -4, 5.2, 0 ]
+---
+# 2x spacing
+- entity:
+ pivot2:
+ spacing: 1
+ spacing: 1
+---
+# 2x ref_point
+- entity:
+ pivot2:
+ ref_point: [ 0, 5.2, 0 ]
+ ref_point: [ 0, 5.2, 0 ]
+---
+# 2x target
+- sun: &sun { dni: 1, spectrum: [{wavelength: 1, data: 1}] }
+- entity:
+ pivot2:
+ target: { sun: *sun }
+ target: { sun: *sun }
+---
+
#
# <anchors> ::=
# anchors:
@@ -901,7 +1074,7 @@
#
# <entity-data> ::=
# name: STRING
-# [ <geometry-data> | <pivot> ]
+# [ <geometry-data> | <pivot> | <pivot2> ]
# [ <anchors> ]
# [ <transform> ]
# [ <children> ]
@@ -929,6 +1102,9 @@
# missing pivot value
- entity: { pivot: }
---
+# missing pivot2 value
+- entity: { pivot2: }
+---
# missing anchors value
- entity: { anchors: }
---
@@ -981,6 +1157,27 @@
target: { sun: *sun }
geometry: [ { stl: { path: "file" } } ]
---
+# cannot define both geometry and pivot2
+- sun: &sun { dni: 1, spectrum: [{wavelength: 1, data: 1}] }
+- entity:
+ pivot2:
+ spacing: 1
+ ref_point: [ 0, 5.2, 0 ]
+ target: { sun: *sun }
+ geometry: [ { stl: { path: "file" } } ]
+---
+# cannot define both pivot and pivot2
+- sun: &sun { dni: 1, spectrum: [{wavelength: 1, data: 1}] }
+- entity:
+ pivot:
+ point: [ -4, 5.2, 0 ]
+ normal: [ -4, 5.2, 0 ]
+ target: { sun: *sun }
+ pivot2:
+ spacing: 1
+ ref_point: [ 0, 5.2, 0 ]
+ target: { sun: *sun }
+---
# 2x anchors
- entity:
anchors:
@@ -1023,7 +1220,7 @@
#
# <entity-data> ::=
# name: STRING
-# [ <geometry-data> | <pivot> ]
+# [ <geometry-data> | <pivot> | <pivot2> ]
# [ <anchors> ]
# [ <transform> ]
# [ <children> ]
@@ -1057,6 +1254,10 @@
- template: &temp { pivot: }
- entity: *temp
---
+# missing pivot2 value
+- template: &temp { pivot2: }
+- entity: *temp
+---
# missing anchors value
- template: &temp { anchors: }
- entity: *temp
@@ -1119,6 +1320,29 @@
geometry: [ { stl: { path: "file" } } ]
- entity: *temp
---
+# cannot define both geometry and pivot2
+- sun: &sun { dni: 1, spectrum: [{wavelength: 1, data: 1}] }
+- template: &temp
+ pivot2:
+ spacing: 1
+ ref_point: [ 0, 5.2, 0 ]
+ target: { sun: *sun }
+ geometry: [ { stl: { path: "file" } } ]
+- entity: *temp
+---
+# cannot define both pivot and pivot2
+- sun: &sun { dni: 1, spectrum: [{wavelength: 1, data: 1}] }
+- template: &temp
+ pivot:
+ point: [ -4, 5.2, 0 ]
+ normal: [ -4, 5.2, 0 ]
+ target: { sun: *sun }
+ pivot2:
+ spacing: 1
+ ref_point: [ 0, 5.2, 0 ]
+ target: { sun: *sun }
+- entity: *temp
+---
# 2x anchors
- template: &temp
anchors:
diff --git a/src/solstice_entity.c b/src/solstice_entity.c
@@ -112,26 +112,25 @@ create_pivot_node
parser_pivot = solparser_get_pivot(solstice->parser, entity->data.pivot);
- /* Setup the pivot descriptor TODO: 2-axis pivots */
anim_pivot.type = PIVOT_SINGLE_AXIS;
d3_set(anim_pivot.data.pivot1.ref_normal, parser_pivot->normal);
d3_set(anim_pivot.data.pivot1.ref_point, parser_pivot->point);
/* Setup the tracking descriptor */
- switch (parser_pivot->target_type) {
+ switch (parser_pivot->target.type) {
case SOLPARSER_TARGET_ANCHOR:
anim_tracking.policy = TRACKING_NODE_TARGET;
target = *htable_anchor_find
- (&solstice->anchors, &parser_pivot->target.anchor.i);
+ (&solstice->anchors, &parser_pivot->target.data.anchor.i);
solstice_node_target_get_tracking(target, &anim_tracking);
break;
case SOLPARSER_TARGET_DIRECTION:
anim_tracking.policy = TRACKING_OUT_DIR;
- d3_set(anim_tracking.data.out_dir.u, parser_pivot->target.direction);
+ d3_set(anim_tracking.data.out_dir.u, parser_pivot->target.data.direction);
break;
case SOLPARSER_TARGET_POSITION:
anim_tracking.policy = TRACKING_POINT;
- d3_set(anim_tracking.data.point.target, parser_pivot->target.position);
+ d3_set(anim_tracking.data.point.target, parser_pivot->target.data.position);
anim_tracking.data.point.target_is_local = 0; /* TODO */
break;
case SOLPARSER_TARGET_SUN:
@@ -158,6 +157,65 @@ error:
}
static struct solstice_node*
+create_pivot2_node
+ (struct solstice* solstice,
+ const struct solparser_entity* entity)
+{
+ struct solstice_node* node = NULL;
+ struct solstice_node* target = NULL;
+ const struct solparser_pivot2* parser_pivot2 = NULL;
+ struct sanim_pivot anim_pivot = SANIM_PIVOT_NULL;
+ struct sanim_tracking anim_tracking = SANIM_TRACKING_NULL;
+ res_T res = RES_OK;
+ ASSERT(solstice && entity);
+
+ parser_pivot2 = solparser_get_pivot2(solstice->parser, entity->data.pivot2);
+
+ anim_pivot.type = PIVOT_TWO_AXIS;
+ anim_pivot.data.pivot2.spacing = parser_pivot2->spacing;
+ d3_set(anim_pivot.data.pivot2.ref_point, parser_pivot2->ref_point);
+
+ /* Setup the tracking descriptor */
+ switch (parser_pivot2->target.type) {
+ case SOLPARSER_TARGET_ANCHOR:
+ anim_tracking.policy = TRACKING_NODE_TARGET;
+ target = *htable_anchor_find
+ (&solstice->anchors, &parser_pivot2->target.data.anchor.i);
+ solstice_node_target_get_tracking(target, &anim_tracking);
+ break;
+ case SOLPARSER_TARGET_DIRECTION:
+ anim_tracking.policy = TRACKING_OUT_DIR;
+ d3_set(anim_tracking.data.out_dir.u, parser_pivot2->target.data.direction);
+ break;
+ case SOLPARSER_TARGET_POSITION:
+ anim_tracking.policy = TRACKING_POINT;
+ d3_set(anim_tracking.data.point.target, parser_pivot2->target.data.position);
+ anim_tracking.data.point.target_is_local = 0; /* TODO */
+ break;
+ case SOLPARSER_TARGET_SUN:
+ anim_tracking.policy = TRACKING_SUN;
+ break;
+ default: FATAL("Unreachable code.\n"); break;
+ }
+
+ res = solstice_node_pivot_create
+ (solstice->allocator, &anim_pivot, &anim_tracking, &node);
+ if (res != RES_OK) goto error;
+
+ res = darray_nodes_push_back(&solstice->pivots, &node);
+ if (res != RES_OK) goto error;
+
+exit:
+ return node;
+error:
+ if (node) {
+ solstice_node_ref_put(node);
+ node = NULL;
+ }
+ goto exit;
+}
+
+static struct solstice_node*
create_node(struct solstice* solstice, const struct solparser_entity* entity)
{
struct solstice_node* node = NULL;
@@ -180,6 +238,9 @@ create_node(struct solstice* solstice, const struct solparser_entity* entity)
case SOLPARSER_ENTITY_PIVOT:
node = create_pivot_node(solstice, entity);
break;
+ case SOLPARSER_ENTITY_PIVOT2:
+ node = create_pivot2_node(solstice, entity);
+ break;
default: FATAL("Unreachable code.\n"); break;
}
if(!node) {