collada: node animation
This commit is contained in:
parent
0489f33243
commit
71744c4344
4
Makefile
4
Makefile
@ -40,8 +40,10 @@ OBJS = \
|
|||||||
src/collada/scene.o \
|
src/collada/scene.o \
|
||||||
src/collada/effect.o \
|
src/collada/effect.o \
|
||||||
src/collada/node_state.o \
|
src/collada/node_state.o \
|
||||||
|
src/collada/animate.o \
|
||||||
data/scenes/ship20/ship20.o \
|
data/scenes/ship20/ship20.o \
|
||||||
data/scenes/noodle/noodle.o
|
data/scenes/noodle/noodle.o \
|
||||||
|
data/scenes/shadow_test/shadow_test.o
|
||||||
|
|
||||||
all: test.so
|
all: test.so
|
||||||
|
|
||||||
|
|||||||
@ -9,3 +9,15 @@ PYTHONPATH=~/d3d10 python -m collada.main \
|
|||||||
|
|
||||||
PYTHONPATH=~/d3d10 python -m collada.main \
|
PYTHONPATH=~/d3d10 python -m collada.main \
|
||||||
include/data/scenes/noodle.h
|
include/data/scenes/noodle.h
|
||||||
|
|
||||||
|
# shadow_test
|
||||||
|
|
||||||
|
PYTHONPATH=~/d3d10 python -m collada.main \
|
||||||
|
~/love-demo/scene/shadow_test/shadow_test.DAE \
|
||||||
|
data/scenes/shadow_test/shadow_test.cpp \
|
||||||
|
data/scenes/shadow_test/shadow_test.vtx \
|
||||||
|
data/scenes/shadow_test/shadow_test.vjw \
|
||||||
|
data/scenes/shadow_test/shadow_test.idx
|
||||||
|
|
||||||
|
PYTHONPATH=~/d3d10 python -m collada.main \
|
||||||
|
include/data/scenes/shadow_test.h
|
||||||
|
|||||||
2279
data/scenes/shadow_test/shadow_test.cpp
Normal file
2279
data/scenes/shadow_test/shadow_test.cpp
Normal file
File diff suppressed because it is too large
Load Diff
BIN
data/scenes/shadow_test/shadow_test.idx
Normal file
BIN
data/scenes/shadow_test/shadow_test.idx
Normal file
Binary file not shown.
0
data/scenes/shadow_test/shadow_test.vjw
Normal file
0
data/scenes/shadow_test/shadow_test.vjw
Normal file
BIN
data/scenes/shadow_test/shadow_test.vtx
Normal file
BIN
data/scenes/shadow_test/shadow_test.vtx
Normal file
Binary file not shown.
15
include/collada/animate.h
Normal file
15
include/collada/animate.h
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
#include "collada/instance_types.h"
|
||||||
|
|
||||||
|
namespace collada::animate {
|
||||||
|
static inline float fract(float f)
|
||||||
|
{
|
||||||
|
return f - floorf(f);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline float loop(float f, float n)
|
||||||
|
{
|
||||||
|
return fract(f / n) * n;
|
||||||
|
}
|
||||||
|
|
||||||
|
void animate_node(instance_types::node& node_instance, float t);
|
||||||
|
}
|
||||||
@ -21,8 +21,12 @@ namespace collada::instance_types {
|
|||||||
types::transform_type type;
|
types::transform_type type;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct node_instance {
|
struct node {
|
||||||
transform * transforms = NULL;
|
// immutable state
|
||||||
|
types::node const * node;
|
||||||
|
|
||||||
|
// mutable state
|
||||||
|
transform * transforms;
|
||||||
XMMATRIX world;
|
XMMATRIX world;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
13
include/collada/node_state.h
Normal file
13
include/collada/node_state.h
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "collada/types.h"
|
||||||
|
#include "collada/instance_types.h"
|
||||||
|
|
||||||
|
namespace collada::node_state {
|
||||||
|
struct state {
|
||||||
|
instance_types::node * node_instances;
|
||||||
|
|
||||||
|
void allocate_node_instances(types::node const * const * const nodes, int nodes_count);
|
||||||
|
void update_node_world_transform(instance_types::node & node_instance);
|
||||||
|
};
|
||||||
|
};
|
||||||
@ -1,6 +1,8 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "collada/types.h"
|
#include "collada/types.h"
|
||||||
|
#include "collada/instance_types.h"
|
||||||
|
#include "collada/node_state.h"
|
||||||
|
|
||||||
namespace collada::scene {
|
namespace collada::scene {
|
||||||
struct static_skinned {
|
struct static_skinned {
|
||||||
@ -10,6 +12,7 @@ namespace collada::scene {
|
|||||||
|
|
||||||
struct state {
|
struct state {
|
||||||
types::descriptor const * descriptor;
|
types::descriptor const * descriptor;
|
||||||
|
node_state::state node_state;
|
||||||
|
|
||||||
unsigned int vertex_buffer_pnt;
|
unsigned int vertex_buffer_pnt;
|
||||||
unsigned int vertex_buffer_jw;
|
unsigned int vertex_buffer_jw;
|
||||||
@ -20,6 +23,7 @@ namespace collada::scene {
|
|||||||
|
|
||||||
unsigned int * textures;
|
unsigned int * textures;
|
||||||
|
|
||||||
|
// drawing
|
||||||
void load_layouts();
|
void load_layouts();
|
||||||
void load_images();
|
void load_images();
|
||||||
void load_scene(types::descriptor const * const descriptor);
|
void load_scene(types::descriptor const * const descriptor);
|
||||||
@ -40,7 +44,13 @@ namespace collada::scene {
|
|||||||
void draw_instance_controllers(types::instance_controller const * const instance_controllers,
|
void draw_instance_controllers(types::instance_controller const * const instance_controllers,
|
||||||
int const instance_controllers_count);
|
int const instance_controllers_count);
|
||||||
|
|
||||||
void draw_node(types::node const & node);
|
void draw_node(types::node const & node, instance_types::node const & node_instance);
|
||||||
void draw();
|
void draw();
|
||||||
|
|
||||||
|
// state updates
|
||||||
|
void update(float t);
|
||||||
|
|
||||||
|
// query
|
||||||
|
instance_types::node * find_node_by_name(char const * name);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@ -362,6 +362,8 @@ namespace collada::types {
|
|||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
struct node {
|
struct node {
|
||||||
|
char const * name;
|
||||||
|
|
||||||
int const parent_index;
|
int const parent_index;
|
||||||
|
|
||||||
node_type const type;
|
node_type const type;
|
||||||
|
|||||||
3
include/data/scenes/shadow_test.h
Normal file
3
include/data/scenes/shadow_test.h
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
namespace shadow_test {
|
||||||
|
extern collada::types::descriptor const descriptor;
|
||||||
|
}
|
||||||
@ -1,14 +1,13 @@
|
|||||||
static inline float fract(float f)
|
#include <stdio.h>
|
||||||
{
|
|
||||||
return f - floorf(f);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline float loop(float f, float n)
|
#include "directxmath/directxmath.h"
|
||||||
{
|
|
||||||
return fract(f / n) * n;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int find_frame_ix(source const& source, float t)
|
#include "collada/types.h"
|
||||||
|
#include "collada/instance_types.h"
|
||||||
|
|
||||||
|
namespace collada::animate {
|
||||||
|
|
||||||
|
static inline int find_frame_ix(types::source const& source, float t)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < source.count - 1; i++) {
|
for (int i = 0; i < source.count - 1; i++) {
|
||||||
if (source.float_array[i] <= t && source.float_array[i+1] > t) {
|
if (source.float_array[i] <= t && source.float_array[i+1] > t) {
|
||||||
@ -18,14 +17,14 @@
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline float linear_interpolate_iv(source const& source, int frame_ix, float t)
|
static inline float linear_interpolate_iv(types::source const& source, int frame_ix, float t)
|
||||||
{
|
{
|
||||||
float prev = source.float_array[(frame_ix+0) * source.stride];
|
float prev = source.float_array[(frame_ix+0) * source.stride];
|
||||||
float next = source.float_array[(frame_ix+1) * source.stride];
|
float next = source.float_array[(frame_ix+1) * source.stride];
|
||||||
return (t - prev) / (next - prev);
|
return (t - prev) / (next - prev);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline float linear_interpolate_value(source const& source, int frame_ix, int parameter_ix, float iv)
|
static inline float linear_interpolate_value(types::source const& source, int frame_ix, int parameter_ix, float iv)
|
||||||
{
|
{
|
||||||
float prev = source.float_array[(frame_ix+0) * source.stride + parameter_ix];
|
float prev = source.float_array[(frame_ix+0) * source.stride + parameter_ix];
|
||||||
float next = source.float_array[(frame_ix+1) * source.stride + parameter_ix];
|
float next = source.float_array[(frame_ix+1) * source.stride + parameter_ix];
|
||||||
@ -76,20 +75,20 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
print("%f %f\n", XMVectorGetX(p0), XMVectorGetY(p0));
|
fprintf(stderr, "%f %f\n", XMVectorGetX(p0), XMVectorGetY(p0));
|
||||||
print("%f %f\n", XMVectorGetX(c0), XMVectorGetY(c0));
|
fprintf(stderr, "%f %f\n", XMVectorGetX(c0), XMVectorGetY(c0));
|
||||||
print("%f %f\n", XMVectorGetX(c1), XMVectorGetY(c1));
|
fprintf(stderr, "%f %f\n", XMVectorGetX(c1), XMVectorGetY(c1));
|
||||||
print("%f %f\n", XMVectorGetX(p1), XMVectorGetY(p1));
|
fprintf(stderr, "%f %f\n", XMVectorGetX(p1), XMVectorGetY(p1));
|
||||||
assert(false);
|
assert(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline XMFLOAT2 const * tangent_index(source const& source, int frame_ix, int parameter_ix)
|
static inline XMFLOAT2 const * tangent_index(types::source const& source, int frame_ix, int parameter_ix)
|
||||||
{
|
{
|
||||||
int ix = frame_ix * source.stride + parameter_ix * 2;
|
int ix = frame_ix * source.stride + parameter_ix * 2;
|
||||||
return (XMFLOAT2 const *)&source.float_array[ix];
|
return (XMFLOAT2 const *)&source.float_array[ix];
|
||||||
}
|
}
|
||||||
|
|
||||||
static float bezier_sampler(sampler const * const sampler, int frame_ix, int parameter_ix, float t)
|
static float bezier_sampler(types::sampler const * const sampler, int frame_ix, int parameter_ix, float t)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
P0 is (INPUT[i] , OUTPUT[i])
|
P0 is (INPUT[i] , OUTPUT[i])
|
||||||
@ -112,25 +111,25 @@
|
|||||||
return bezier_binary_search(p0, c0, c1, p1, t);
|
return bezier_binary_search(p0, c0, c1, p1, t);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void apply_transform_target(transform& transform,
|
static void apply_transform_target(instance_types::transform& transform,
|
||||||
enum target_attribute channel_target_attribute,
|
enum types::target_attribute channel_target_attribute,
|
||||||
float value)
|
float value)
|
||||||
{
|
{
|
||||||
switch (transform.type) {
|
switch (transform.type) {
|
||||||
case transform_type::TRANSLATE: __attribute__((fallthrough));
|
case types::transform_type::TRANSLATE: __attribute__((fallthrough));
|
||||||
case transform_type::SCALE:
|
case types::transform_type::SCALE:
|
||||||
switch (channel_target_attribute) {
|
switch (channel_target_attribute) {
|
||||||
case target_attribute::X: transform.vector = XMVectorSetX(transform.vector, value); return;
|
case types::target_attribute::X: transform.vector = XMVectorSetX(transform.vector, value); return;
|
||||||
case target_attribute::Y: transform.vector = XMVectorSetY(transform.vector, value); return;
|
case types::target_attribute::Y: transform.vector = XMVectorSetY(transform.vector, value); return;
|
||||||
case target_attribute::Z: transform.vector = XMVectorSetZ(transform.vector, value); return;
|
case types::target_attribute::Z: transform.vector = XMVectorSetZ(transform.vector, value); return;
|
||||||
default: assert(false);
|
default: assert(false);
|
||||||
}
|
}
|
||||||
case transform_type::ROTATE:
|
case types::transform_type::ROTATE:
|
||||||
switch (channel_target_attribute) {
|
switch (channel_target_attribute) {
|
||||||
case target_attribute::X: transform.vector = XMVectorSetX(transform.vector, value); return;
|
case types::target_attribute::X: transform.vector = XMVectorSetX(transform.vector, value); return;
|
||||||
case target_attribute::Y: transform.vector = XMVectorSetY(transform.vector, value); return;
|
case types::target_attribute::Y: transform.vector = XMVectorSetY(transform.vector, value); return;
|
||||||
case target_attribute::Z: transform.vector = XMVectorSetZ(transform.vector, value); return;
|
case types::target_attribute::Z: transform.vector = XMVectorSetZ(transform.vector, value); return;
|
||||||
case target_attribute::ANGLE: transform.vector = XMVectorSetW(transform.vector, value); return;
|
case types::target_attribute::ANGLE: transform.vector = XMVectorSetW(transform.vector, value); return;
|
||||||
default: assert(false);
|
default: assert(false);
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
@ -139,33 +138,33 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static enum target_attribute const rotate_target_attributes[] = {
|
static enum types::target_attribute const rotate_target_attributes[] = {
|
||||||
target_attribute::X,
|
types::target_attribute::X,
|
||||||
target_attribute::Y,
|
types::target_attribute::Y,
|
||||||
target_attribute::Z,
|
types::target_attribute::Z,
|
||||||
target_attribute::ANGLE,
|
types::target_attribute::ANGLE,
|
||||||
};
|
};
|
||||||
|
|
||||||
static enum target_attribute const translate_scale_target_attributes[] = {
|
static enum types::target_attribute const translate_scale_target_attributes[] = {
|
||||||
target_attribute::X,
|
types::target_attribute::X,
|
||||||
target_attribute::Y,
|
types::target_attribute::Y,
|
||||||
target_attribute::Z,
|
types::target_attribute::Z,
|
||||||
};
|
};
|
||||||
|
|
||||||
static void animate_channel_segment(channel const& channel,
|
static void animate_channel_segment(types::channel const& channel,
|
||||||
transform& transform,
|
instance_types::transform& transform,
|
||||||
int frame_ix, float t)
|
int frame_ix, float t)
|
||||||
{
|
{
|
||||||
enum target_attribute const * target_attributes = &channel.target_attribute;
|
enum types::target_attribute const * target_attributes = &channel.target_attribute;
|
||||||
int target_attributes_count = 1;
|
int target_attributes_count = 1;
|
||||||
if (channel.target_attribute == target_attribute::ALL) {
|
if (channel.target_attribute == types::target_attribute::ALL) {
|
||||||
switch (transform.type) {
|
switch (transform.type) {
|
||||||
case transform_type::TRANSLATE: __attribute__((fallthrough));
|
case types::transform_type::TRANSLATE: __attribute__((fallthrough));
|
||||||
case transform_type::SCALE:
|
case types::transform_type::SCALE:
|
||||||
target_attributes = translate_scale_target_attributes;
|
target_attributes = translate_scale_target_attributes;
|
||||||
target_attributes_count = 3;
|
target_attributes_count = 3;
|
||||||
break;
|
break;
|
||||||
case transform_type::ROTATE:
|
case types::transform_type::ROTATE:
|
||||||
target_attributes = rotate_target_attributes;
|
target_attributes = rotate_target_attributes;
|
||||||
target_attributes_count = 4;
|
target_attributes_count = 4;
|
||||||
break;
|
break;
|
||||||
@ -177,10 +176,10 @@
|
|||||||
|
|
||||||
for (int parameter_ix = 0; parameter_ix < target_attributes_count; parameter_ix++) {
|
for (int parameter_ix = 0; parameter_ix < target_attributes_count; parameter_ix++) {
|
||||||
|
|
||||||
enum collada::interpolation interpolation = channel.source_sampler->interpolation.interpolation_array[frame_ix];
|
enum types::interpolation interpolation = channel.source_sampler->interpolation.interpolation_array[frame_ix];
|
||||||
|
|
||||||
float value;
|
float value;
|
||||||
if (interpolation == interpolation::BEZIER) {
|
if (interpolation == types::interpolation::BEZIER) {
|
||||||
value = bezier_sampler(channel.source_sampler, frame_ix, parameter_ix, t);
|
value = bezier_sampler(channel.source_sampler, frame_ix, parameter_ix, t);
|
||||||
} else {
|
} else {
|
||||||
float iv = linear_interpolate_iv(channel.source_sampler->input, frame_ix, t);
|
float iv = linear_interpolate_iv(channel.source_sampler->input, frame_ix, t);
|
||||||
@ -191,11 +190,11 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void animate_node(node const& node, node_instance& node_instance, float t)
|
void animate_node(instance_types::node& node_instance, float t)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < node.channels_count; i++) {
|
for (int i = 0; i < node_instance.node->channels_count; i++) {
|
||||||
channel const& channel = *node.channels[i];
|
types::channel const& channel = *node_instance.node->channels[i];
|
||||||
transform& transform = node_instance.transforms[channel.target_transform_index];
|
instance_types::transform& transform = node_instance.transforms[channel.target_transform_index];
|
||||||
|
|
||||||
int frame_ix = find_frame_ix(channel.source_sampler->input, t);
|
int frame_ix = find_frame_ix(channel.source_sampler->input, t);
|
||||||
assert(frame_ix >= 0); // animation is missing a key frame
|
assert(frame_ix >= 0); // animation is missing a key frame
|
||||||
@ -203,3 +202,4 @@
|
|||||||
animate_channel_segment(channel, transform, frame_ix, t);
|
animate_channel_segment(channel, transform, frame_ix, t);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|||||||
@ -1,11 +1,19 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
#include "directxmath/directxmath.h"
|
#include "directxmath/directxmath.h"
|
||||||
|
|
||||||
#include "collada/types.h"
|
#include "new.h"
|
||||||
#include "collada/instance_types.h"
|
|
||||||
|
#include "collada/node_state.h"
|
||||||
|
|
||||||
namespace collada::node_state {
|
namespace collada::node_state {
|
||||||
inline static void load_transform(instance_types::transform * instance_transform,
|
|
||||||
types::transform const & transform)
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
// transforms
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
inline static void load_transform(types::transform const & transform,
|
||||||
|
instance_types::transform * instance_transform)
|
||||||
{
|
{
|
||||||
switch (transform.type) {
|
switch (transform.type) {
|
||||||
case types::transform_type::LOOKAT:
|
case types::transform_type::LOOKAT:
|
||||||
@ -28,17 +36,37 @@ namespace collada::node_state {
|
|||||||
default:
|
default:
|
||||||
assert(false);
|
assert(false);
|
||||||
}
|
}
|
||||||
|
instance_transform->type = transform.type;
|
||||||
}
|
}
|
||||||
|
|
||||||
void initialize_node_transforms(types::node const * const node,
|
inline static void initialize_node_transforms(instance_types::node & node_instance)
|
||||||
instance_types::node_instance * const node_instance)
|
|
||||||
{
|
{
|
||||||
for (int i = 0; i < node->transforms_count; i++) {
|
for (int i = 0; i < node_instance.node->transforms_count; i++) {
|
||||||
load_transform(&node_instance->transforms[i],
|
load_transform(node_instance.node->transforms[i], &node_instance.transforms[i]);
|
||||||
node->transforms[i]);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline static void allocate_node_instance(instance_types::node & node_instance,
|
||||||
|
types::node const * const node)
|
||||||
|
{
|
||||||
|
node_instance.node = node;
|
||||||
|
node_instance.transforms = New<instance_types::transform>(node->transforms_count);
|
||||||
|
|
||||||
|
initialize_node_transforms(node_instance);
|
||||||
|
}
|
||||||
|
|
||||||
|
void state::allocate_node_instances(types::node const * const * const nodes, int nodes_count)
|
||||||
|
{
|
||||||
|
node_instances = New<instance_types::node>(nodes_count);
|
||||||
|
for (int i = 0; i < nodes_count; i++) {
|
||||||
|
allocate_node_instance(node_instances[i], nodes[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
// world matrix
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
inline static bool vector_equal(XMVECTOR V1, XMVECTOR V2)
|
inline static bool vector_equal(XMVECTOR V1, XMVECTOR V2)
|
||||||
{
|
{
|
||||||
uint32_t CR;
|
uint32_t CR;
|
||||||
@ -60,8 +88,25 @@ namespace collada::node_state {
|
|||||||
case types::transform_type::MATRIX:
|
case types::transform_type::MATRIX:
|
||||||
return transform.matrix;
|
return transform.matrix;
|
||||||
default:
|
default:
|
||||||
|
fprintf(stderr, "unknown transform type %d\n", (int)transform.type);
|
||||||
assert(false);
|
assert(false);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void state::update_node_world_transform(instance_types::node & node_instance)
|
||||||
|
{
|
||||||
|
XMMATRIX world;
|
||||||
|
|
||||||
|
if (node_instance.node->parent_index >= 0)
|
||||||
|
world = node_instances[node_instance.node->parent_index].world;
|
||||||
|
else
|
||||||
|
world = XMMatrixIdentity();
|
||||||
|
|
||||||
|
for (int i = 0; i < node_instance.node->transforms_count; i++) {
|
||||||
|
world = transform_matrix(node_instance.transforms[i]) * world;
|
||||||
|
}
|
||||||
|
|
||||||
|
node_instance.world = world;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -14,6 +14,7 @@
|
|||||||
#include "collada/instance_types.h"
|
#include "collada/instance_types.h"
|
||||||
#include "collada/scene.h"
|
#include "collada/scene.h"
|
||||||
#include "collada/effect.h"
|
#include "collada/effect.h"
|
||||||
|
#include "collada/animate.h"
|
||||||
|
|
||||||
namespace collada::scene {
|
namespace collada::scene {
|
||||||
|
|
||||||
@ -275,6 +276,8 @@ namespace collada::scene {
|
|||||||
index_buffer = load_index_buffer(descriptor->index_buffer);
|
index_buffer = load_index_buffer(descriptor->index_buffer);
|
||||||
|
|
||||||
load_images();
|
load_images();
|
||||||
|
|
||||||
|
node_state.allocate_node_instances(descriptor->nodes, descriptor->nodes_count);
|
||||||
}
|
}
|
||||||
|
|
||||||
void state::set_color_or_texture(types::color_or_texture const& color_or_texture,
|
void state::set_color_or_texture(types::color_or_texture const& color_or_texture,
|
||||||
@ -337,8 +340,6 @@ namespace collada::scene {
|
|||||||
types::instance_material const * const instance_materials,
|
types::instance_material const * const instance_materials,
|
||||||
int const instance_materials_count)
|
int const instance_materials_count)
|
||||||
{
|
{
|
||||||
glUseProgram(collada::effect::program_static);
|
|
||||||
|
|
||||||
types::mesh const& mesh = geometry.mesh;
|
types::mesh const& mesh = geometry.mesh;
|
||||||
|
|
||||||
for (int j = 0; j < instance_materials_count; j++) {
|
for (int j = 0; j < instance_materials_count; j++) {
|
||||||
@ -437,10 +438,23 @@ namespace collada::scene {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void state::draw_node(types::node const & node)
|
void state::draw_node(types::node const & node, instance_types::node const & node_instance)
|
||||||
{
|
{
|
||||||
draw_instance_geometries(node.instance_geometries, node.instance_geometries_count);
|
XMMATRIX transform = node_instance.world * view::state.transform;
|
||||||
draw_instance_controllers(node.instance_controllers, node.instance_controllers_count);
|
XMFLOAT4X4 float_transform;
|
||||||
|
XMStoreFloat4x4(&float_transform, transform);
|
||||||
|
|
||||||
|
if (node.instance_geometries_count) {
|
||||||
|
glUseProgram(collada::effect::program_static);
|
||||||
|
glUniformMatrix4fv(layout.uniform.transform, 1, false, (float *)&float_transform);
|
||||||
|
draw_instance_geometries(node.instance_geometries, node.instance_geometries_count);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (node.instance_controllers_count) {
|
||||||
|
glUseProgram(collada::effect::program_static);
|
||||||
|
glUniformMatrix4fv(layout.uniform.transform, 1, false, (float *)&float_transform);
|
||||||
|
draw_instance_controllers(node.instance_controllers, node.instance_controllers_count);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void state::draw()
|
void state::draw()
|
||||||
@ -448,7 +462,6 @@ namespace collada::scene {
|
|||||||
unsigned int effects[] = {collada::effect::program_static, collada::effect::program_skinned};
|
unsigned int effects[] = {collada::effect::program_static, collada::effect::program_skinned};
|
||||||
for (int i = 0; i < 2; i++) {
|
for (int i = 0; i < 2; i++) {
|
||||||
glUseProgram(effects[i]);
|
glUseProgram(effects[i]);
|
||||||
glUniformMatrix4fv(layout.uniform.transform, 1, false, (float *)&view::state.float_transform);
|
|
||||||
glUniform1i(layout.uniform.emission_sampler, 0);
|
glUniform1i(layout.uniform.emission_sampler, 0);
|
||||||
glUniform1i(layout.uniform.ambient_sampler, 1);
|
glUniform1i(layout.uniform.ambient_sampler, 1);
|
||||||
glUniform1i(layout.uniform.diffuse_sampler, 2);
|
glUniform1i(layout.uniform.diffuse_sampler, 2);
|
||||||
@ -468,7 +481,27 @@ namespace collada::scene {
|
|||||||
if (node.type != types::node_type::NODE)
|
if (node.type != types::node_type::NODE)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
draw_node(node);
|
draw_node(node, node_state.node_instances[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void state::update(float t)
|
||||||
|
{
|
||||||
|
t = animate::loop(t / 4.0f, 3.333333f);
|
||||||
|
|
||||||
|
for (int i = 0; i < descriptor->nodes_count; i++) {
|
||||||
|
animate::animate_node(node_state.node_instances[i], t);
|
||||||
|
node_state.update_node_world_transform(node_state.node_instances[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
instance_types::node * state::find_node_by_name(char const * name)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < descriptor->nodes_count; i++) {
|
||||||
|
if (strcmp(node_state.node_instances[i].node->name, name) == 0) {
|
||||||
|
return &node_state.node_instances[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
22
src/test.cpp
22
src/test.cpp
@ -24,9 +24,11 @@
|
|||||||
#include "collada/effect.h"
|
#include "collada/effect.h"
|
||||||
#include "collada/scene.h"
|
#include "collada/scene.h"
|
||||||
#include "collada/types.h"
|
#include "collada/types.h"
|
||||||
|
#include "collada/instance_types.h"
|
||||||
|
|
||||||
#include "data/scenes/ship20.h"
|
#include "data/scenes/ship20.h"
|
||||||
#include "data/scenes/noodle.h"
|
#include "data/scenes/noodle.h"
|
||||||
|
#include "data/scenes/shadow_test.h"
|
||||||
|
|
||||||
struct line_location {
|
struct line_location {
|
||||||
struct {
|
struct {
|
||||||
@ -73,6 +75,9 @@ static target_type const geometry_buffer_pnc_types[3] = {
|
|||||||
[target_name::COLOR] = { GL_RGBA8, GL_COLOR_ATTACHMENT2 },
|
[target_name::COLOR] = { GL_RGBA8, GL_COLOR_ATTACHMENT2 },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
collada::instance_types::node * node_eye;
|
||||||
|
collada::instance_types::node * node_at;
|
||||||
|
|
||||||
void load_quad_index_buffer()
|
void load_quad_index_buffer()
|
||||||
{
|
{
|
||||||
uint8_t const data[] = {
|
uint8_t const data[] = {
|
||||||
@ -304,7 +309,11 @@ void load(const char * source_path)
|
|||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
collada::effect::load_effects();
|
collada::effect::load_effects();
|
||||||
scene_state.load_scene(&noodle::descriptor);
|
scene_state.load_scene(&shadow_test::descriptor);
|
||||||
|
node_eye = scene_state.find_node_by_name("Camera001");
|
||||||
|
assert(node_eye != nullptr);
|
||||||
|
node_at = scene_state.find_node_by_name("Camera001.Target");
|
||||||
|
assert(node_at != nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void update_keyboard(int up, int down, int left, int right,
|
void update_keyboard(int up, int down, int left, int right,
|
||||||
@ -416,8 +425,11 @@ void update_joystick(int joystick_index,
|
|||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
view::state.at = view::state.at + direction;
|
view::state.eye = view::state.eye + direction;
|
||||||
view::state.eye = view::state.at - view::state.direction * view::at_distance;
|
//view::state.at = view::state.at - view::state.direction * view::at_distance;
|
||||||
|
|
||||||
|
//view::state.at = view::state.at + direction;
|
||||||
|
//view::state.eye = view::state.at - view::state.direction * view::at_distance;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
lighting.quadratic += 0.01 * a + -0.01 * b;
|
lighting.quadratic += 0.01 * a + -0.01 * b;
|
||||||
@ -440,6 +452,10 @@ void update(float time)
|
|||||||
{
|
{
|
||||||
current_time = time;
|
current_time = time;
|
||||||
|
|
||||||
|
scene_state.update(time);
|
||||||
|
view::state.eye = XMVector3Transform(XMVectorZero(), node_eye->world);
|
||||||
|
view::state.at = XMVector3Transform(XMVectorZero(), node_at->world);
|
||||||
|
|
||||||
view::update_transforms();
|
view::update_transforms();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user