97 lines
3.8 KiB
C
97 lines
3.8 KiB
C
#pragma once
|
|
|
|
#include"node.h"
|
|
|
|
static inline size_t bisect(const void *key, const void *base, size_t nmemb, size_t size, ssize_t(*compar)(const void*, const void*)) {
|
|
size_t low = 0, high = nmemb;
|
|
|
|
while(low < high) {
|
|
size_t middle = (low + high) / 2;
|
|
if(compar((const void*) ((uintptr_t) base + size * middle), key) < 0) {
|
|
low = middle + 1;
|
|
} else {
|
|
high = middle;
|
|
}
|
|
}
|
|
|
|
return low;
|
|
}
|
|
|
|
static inline ssize_t float_compar(const void *A, const void *B) {
|
|
float a = *(float*) A;
|
|
float b = *(float*) B;
|
|
return (a > b) - (a < b);
|
|
}
|
|
|
|
static inline int adjacencycmp(const void *a, const void *b) {
|
|
size_t v = (uintptr_t) ((CHiAdjacency*) a)[0] - (uintptr_t) ((CHiAdjacency*) b)[0];
|
|
return v ? v : (uintptr_t) ((CHiAdjacency*) a)[1] - (uintptr_t) ((CHiAdjacency*) b)[1];
|
|
}
|
|
|
|
static inline void adjacency_add(CHiPubNode *source, CHiPubNode *sink) {
|
|
CHiNodeGraph *ng = source->ng;
|
|
|
|
if(ng->adjacencyCount == ng->adjacencyCapacity) {
|
|
ng->adjacencies = realloc(ng->adjacencies, sizeof(CHiAdjacency) * (ng->adjacencyCapacity *= 2));
|
|
}
|
|
|
|
ng->adjacencies[ng->adjacencyCount][0] = source;
|
|
ng->adjacencies[ng->adjacencyCount][1] = sink;
|
|
ng->adjacencyCount++;
|
|
|
|
qsort(ng->adjacencies, ng->adjacencyCount, sizeof(CHiAdjacency), adjacencycmp);
|
|
}
|
|
|
|
static inline void adjacency_remove(CHiPubNode *source, CHiPubNode *sink) {
|
|
CHiNodeGraph *ng = source->ng;
|
|
|
|
CHiAdjacency *adj = bsearch(&(CHiAdjacency) {source, sink}, ng->adjacencies, ng->adjacencyCount, sizeof(CHiAdjacency), adjacencycmp);
|
|
if(adj) {
|
|
memmove(adj, adj + 1, sizeof(CHiAdjacency) * (ng->adjacencyCount - (adj - ng->adjacencies) - 1));
|
|
ng->adjacencyCount--;
|
|
}
|
|
}
|
|
|
|
static inline void update_keyed_values(CHiNodeGraph *ng) {
|
|
for(size_t kfsIdx = 0; kfsIdx < ng->keyframesList.count; kfsIdx++) {
|
|
CHiKeyframes *kfs = ng->keyframesList.keyframes[kfsIdx];
|
|
|
|
kfs->current.type = kfs->type;
|
|
|
|
float now = ng->time;
|
|
|
|
size_t idx = bisect(&now, kfs->times, kfs->count, sizeof(now), float_compar);
|
|
|
|
if(idx == 0) {
|
|
kfs->current.data = kfs->values[idx];
|
|
|
|
if(kfs->current.type == CUTIHI_VAL_VEC4 && kfs->extrapolationMode == CUTIHI_EXTRAPOLATION_CONSTANT) {
|
|
kfs->current.data.vec4[0] += (now - kfs->times[0]) * kfs->extrapolationParameter[0];
|
|
kfs->current.data.vec4[1] += (now - kfs->times[0]) * kfs->extrapolationParameter[1];
|
|
kfs->current.data.vec4[2] += (now - kfs->times[0]) * kfs->extrapolationParameter[2];
|
|
kfs->current.data.vec4[3] += (now - kfs->times[0]) * kfs->extrapolationParameter[3];
|
|
}
|
|
} else if(idx == kfs->count) {
|
|
kfs->current.data = kfs->values[idx - 1];
|
|
|
|
if(kfs->current.type == CUTIHI_VAL_VEC4 && kfs->extrapolationMode == CUTIHI_EXTRAPOLATION_CONSTANT) {
|
|
kfs->current.data.vec4[0] += (now - kfs->times[kfs->count - 1]) * kfs->extrapolationParameter[0];
|
|
kfs->current.data.vec4[1] += (now - kfs->times[kfs->count - 1]) * kfs->extrapolationParameter[1];
|
|
kfs->current.data.vec4[2] += (now - kfs->times[kfs->count - 1]) * kfs->extrapolationParameter[2];
|
|
kfs->current.data.vec4[3] += (now - kfs->times[kfs->count - 1]) * kfs->extrapolationParameter[3];
|
|
}
|
|
} else {
|
|
if(kfs->type == CUTIHI_VAL_VEC4) {
|
|
float alpha = (now - kfs->times[idx - 1]) / (kfs->times[idx] - kfs->times[idx - 1]);
|
|
|
|
kfs->current.data.vec4[0] = kfs->values[idx - 1].vec4[0] + (kfs->values[idx].vec4[0] - kfs->values[idx - 1].vec4[0]) * alpha;
|
|
kfs->current.data.vec4[1] = kfs->values[idx - 1].vec4[1] + (kfs->values[idx].vec4[1] - kfs->values[idx - 1].vec4[1]) * alpha;
|
|
kfs->current.data.vec4[2] = kfs->values[idx - 1].vec4[2] + (kfs->values[idx].vec4[2] - kfs->values[idx - 1].vec4[2]) * alpha;
|
|
kfs->current.data.vec4[3] = kfs->values[idx - 1].vec4[3] + (kfs->values[idx].vec4[3] - kfs->values[idx - 1].vec4[3]) * alpha;
|
|
} else {
|
|
kfs->current.data = kfs->values[idx - 1];
|
|
}
|
|
}
|
|
}
|
|
}
|