collada: animated book
This commit is contained in:
parent
f4e95aee09
commit
2b379aa27c
3
Makefile
3
Makefile
@ -43,7 +43,8 @@ OBJS = \
|
|||||||
src/collada/animate.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
|
data/scenes/shadow_test/shadow_test.o \
|
||||||
|
data/scenes/book/book.o
|
||||||
|
|
||||||
all: test.so
|
all: test.so
|
||||||
|
|
||||||
|
|||||||
@ -21,3 +21,15 @@ PYTHONPATH=~/d3d10 python -m collada.main \
|
|||||||
|
|
||||||
PYTHONPATH=~/d3d10 python -m collada.main \
|
PYTHONPATH=~/d3d10 python -m collada.main \
|
||||||
include/data/scenes/shadow_test.h
|
include/data/scenes/shadow_test.h
|
||||||
|
|
||||||
|
# book
|
||||||
|
|
||||||
|
PYTHONPATH=~/d3d10 python -m collada.main \
|
||||||
|
~/Downloads/book.DAE \
|
||||||
|
data/scenes/book/book.cpp \
|
||||||
|
data/scenes/book/book.vtx \
|
||||||
|
data/scenes/book/book.vjw \
|
||||||
|
data/scenes/book/book.idx
|
||||||
|
|
||||||
|
PYTHONPATH=~/d3d10 python -m collada.main \
|
||||||
|
include/data/scenes/book.h
|
||||||
|
|||||||
4616
data/scenes/book/book.cpp
Normal file
4616
data/scenes/book/book.cpp
Normal file
File diff suppressed because it is too large
Load Diff
BIN
data/scenes/book/book.idx
Normal file
BIN
data/scenes/book/book.idx
Normal file
Binary file not shown.
BIN
data/scenes/book/book.vjw
Normal file
BIN
data/scenes/book/book.vjw
Normal file
Binary file not shown.
BIN
data/scenes/book/book.vtx
Normal file
BIN
data/scenes/book/book.vtx
Normal file
Binary file not shown.
@ -260,6 +260,7 @@ namespace collada::types {
|
|||||||
struct skin {
|
struct skin {
|
||||||
types::geometry const * const geometry; // source
|
types::geometry const * const geometry; // source
|
||||||
|
|
||||||
|
matrix const bind_shape_matrix; // one per skin
|
||||||
matrix const * const inverse_bind_matrices; // one per joint
|
matrix const * const inverse_bind_matrices; // one per joint
|
||||||
|
|
||||||
int const vertex_buffer_offset;
|
int const vertex_buffer_offset;
|
||||||
|
|||||||
3
include/data/scenes/book.h
Normal file
3
include/data/scenes/book.h
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
namespace book {
|
||||||
|
extern collada::types::descriptor const descriptor;
|
||||||
|
}
|
||||||
@ -7,27 +7,32 @@
|
|||||||
|
|
||||||
namespace collada::animate {
|
namespace collada::animate {
|
||||||
|
|
||||||
static inline int find_frame_ix(types::source const& source, float t)
|
struct frame_ix {
|
||||||
|
int f0;
|
||||||
|
int f1;
|
||||||
|
};
|
||||||
|
|
||||||
|
static inline frame_ix 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) {
|
||||||
return i;
|
return {i, i + 1};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return -1;
|
return {source.count - 1, 0};
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline float linear_interpolate_iv(types::source const& source, int frame_ix, float t)
|
static inline float linear_interpolate_iv(types::source const& source, frame_ix frame_ix, float t)
|
||||||
{
|
{
|
||||||
float prev = source.float_array[(frame_ix+0) * source.stride];
|
float prev = source.float_array[(frame_ix.f0) * source.stride];
|
||||||
float next = source.float_array[(frame_ix+1) * source.stride];
|
float next = source.float_array[(frame_ix.f1) * source.stride];
|
||||||
return (t - prev) / (next - prev);
|
return (t - prev) / (next - prev);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline float linear_interpolate_value(types::source const& source, int frame_ix, int parameter_ix, float iv)
|
static inline float linear_interpolate_value(types::source const& source, frame_ix 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.f0) * source.stride + parameter_ix];
|
||||||
float next = source.float_array[(frame_ix+1) * source.stride + parameter_ix];
|
float next = source.float_array[(frame_ix.f1) * source.stride + parameter_ix];
|
||||||
return prev + iv * (next - prev);
|
return prev + iv * (next - prev);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -88,7 +93,7 @@ namespace collada::animate {
|
|||||||
return (XMFLOAT2 const *)&source.float_array[ix];
|
return (XMFLOAT2 const *)&source.float_array[ix];
|
||||||
}
|
}
|
||||||
|
|
||||||
static float bezier_sampler(types::sampler const * const sampler, int frame_ix, int parameter_ix, float t)
|
static float bezier_sampler(types::sampler const * const sampler, frame_ix frame_ix, int parameter_ix, float t)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
P0 is (INPUT[i] , OUTPUT[i])
|
P0 is (INPUT[i] , OUTPUT[i])
|
||||||
@ -97,15 +102,15 @@ namespace collada::animate {
|
|||||||
P1 is (INPUT[i+1], OUTPUT[i+1])
|
P1 is (INPUT[i+1], OUTPUT[i+1])
|
||||||
*/
|
*/
|
||||||
|
|
||||||
float frame0_input = sampler->input.float_array[frame_ix+0];
|
float frame0_input = sampler->input.float_array[frame_ix.f0];
|
||||||
float frame1_input = sampler->input.float_array[frame_ix+1];
|
float frame1_input = sampler->input.float_array[frame_ix.f1];
|
||||||
|
|
||||||
float frame0_output = sampler->output.float_array[(frame_ix+0) * sampler->output.stride + parameter_ix];
|
float frame0_output = sampler->output.float_array[(frame_ix.f0) * sampler->output.stride + parameter_ix];
|
||||||
float frame1_output = sampler->output.float_array[(frame_ix+1) * sampler->output.stride + parameter_ix];
|
float frame1_output = sampler->output.float_array[(frame_ix.f1) * sampler->output.stride + parameter_ix];
|
||||||
|
|
||||||
XMVECTOR p0 = XMVectorSet(frame0_input, frame0_output, 0, 0);
|
XMVECTOR p0 = XMVectorSet(frame0_input, frame0_output, 0, 0);
|
||||||
XMVECTOR c0 = XMLoadFloat2(tangent_index(sampler->out_tangent, frame_ix + 0, parameter_ix));
|
XMVECTOR c0 = XMLoadFloat2(tangent_index(sampler->out_tangent, frame_ix.f0, parameter_ix));
|
||||||
XMVECTOR c1 = XMLoadFloat2(tangent_index(sampler->in_tangent, frame_ix + 1, parameter_ix));
|
XMVECTOR c1 = XMLoadFloat2(tangent_index(sampler->in_tangent, frame_ix.f1, parameter_ix));
|
||||||
XMVECTOR p1 = XMVectorSet(frame1_input, frame1_output, 0, 0);
|
XMVECTOR p1 = XMVectorSet(frame1_input, frame1_output, 0, 0);
|
||||||
|
|
||||||
return bezier_binary_search(p0, c0, c1, p1, t);
|
return bezier_binary_search(p0, c0, c1, p1, t);
|
||||||
@ -153,7 +158,7 @@ namespace collada::animate {
|
|||||||
|
|
||||||
static void animate_channel_segment(types::channel const& channel,
|
static void animate_channel_segment(types::channel const& channel,
|
||||||
instance_types::transform& transform,
|
instance_types::transform& transform,
|
||||||
int frame_ix, float t)
|
frame_ix frame_ix, float t)
|
||||||
{
|
{
|
||||||
enum types::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;
|
||||||
@ -176,7 +181,7 @@ namespace collada::animate {
|
|||||||
|
|
||||||
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 types::interpolation interpolation = channel.source_sampler->interpolation.interpolation_array[frame_ix];
|
enum types::interpolation interpolation = channel.source_sampler->interpolation.interpolation_array[frame_ix.f0];
|
||||||
|
|
||||||
float value;
|
float value;
|
||||||
if (interpolation == types::interpolation::BEZIER) {
|
if (interpolation == types::interpolation::BEZIER) {
|
||||||
@ -196,8 +201,8 @@ namespace collada::animate {
|
|||||||
types::channel const& channel = *node_instance.node->channels[i];
|
types::channel const& channel = *node_instance.node->channels[i];
|
||||||
instance_types::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);
|
frame_ix 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
|
||||||
|
|
||||||
animate_channel_segment(channel, transform, frame_ix, t);
|
animate_channel_segment(channel, transform, frame_ix, t);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -450,6 +450,8 @@ namespace collada::scene {
|
|||||||
types::instance_controller const &instance_controller = instance_controllers[i];
|
types::instance_controller const &instance_controller = instance_controllers[i];
|
||||||
types::skin const &skin = instance_controller.controller->skin;
|
types::skin const &skin = instance_controller.controller->skin;
|
||||||
|
|
||||||
|
XMMATRIX bsm = XMLoadFloat4x4((XMFLOAT4X4*)&skin.bind_shape_matrix);
|
||||||
|
|
||||||
XMFLOAT4X4 joints[instance_controller.joint_count];
|
XMFLOAT4X4 joints[instance_controller.joint_count];
|
||||||
int joints_size = (sizeof (joints));
|
int joints_size = (sizeof (joints));
|
||||||
for (int joint_index = 0; joint_index < instance_controller.joint_count; joint_index++) {
|
for (int joint_index = 0; joint_index < instance_controller.joint_count; joint_index++) {
|
||||||
@ -457,7 +459,7 @@ namespace collada::scene {
|
|||||||
int node_index = instance_controller.joint_node_indices[joint_index];
|
int node_index = instance_controller.joint_node_indices[joint_index];
|
||||||
instance_types::node& node_instance = node_state.node_instances[node_index];
|
instance_types::node& node_instance = node_state.node_instances[node_index];
|
||||||
|
|
||||||
XMStoreFloat4x4(&joints[joint_index], ibm * node_instance.world);
|
XMStoreFloat4x4(&joints[joint_index], bsm * ibm * node_instance.world);
|
||||||
}
|
}
|
||||||
glBindBuffer(GL_UNIFORM_BUFFER, joint_uniform_buffer);
|
glBindBuffer(GL_UNIFORM_BUFFER, joint_uniform_buffer);
|
||||||
glBufferData(GL_UNIFORM_BUFFER, joints_size, (void *)&joints[0], GL_DYNAMIC_DRAW);
|
glBufferData(GL_UNIFORM_BUFFER, joints_size, (void *)&joints[0], GL_DYNAMIC_DRAW);
|
||||||
@ -520,7 +522,7 @@ namespace collada::scene {
|
|||||||
|
|
||||||
void state::update(float t)
|
void state::update(float t)
|
||||||
{
|
{
|
||||||
t = animate::loop(t / 4.0f, 3.333333f);
|
t = animate::loop(t / 4.0f, 1.8333333333333333f);
|
||||||
|
|
||||||
for (int i = 0; i < descriptor->nodes_count; i++) {
|
for (int i = 0; i < descriptor->nodes_count; i++) {
|
||||||
animate::animate_node(node_state.node_instances[i], t);
|
animate::animate_node(node_state.node_instances[i], t);
|
||||||
|
|||||||
18
src/test.cpp
18
src/test.cpp
@ -29,6 +29,7 @@
|
|||||||
#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"
|
#include "data/scenes/shadow_test.h"
|
||||||
|
#include "data/scenes/book.h"
|
||||||
|
|
||||||
struct line_location {
|
struct line_location {
|
||||||
struct {
|
struct {
|
||||||
@ -309,11 +310,13 @@ void load(const char * source_path)
|
|||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
collada::effect::load_effects();
|
collada::effect::load_effects();
|
||||||
scene_state.load_scene(&noodle::descriptor);
|
scene_state.load_scene(&book::descriptor);
|
||||||
node_eye = scene_state.find_node_by_name("Camera001");
|
node_eye = scene_state.find_node_by_name("Camera");
|
||||||
assert(node_eye != nullptr);
|
assert(node_eye != nullptr);
|
||||||
node_at = scene_state.find_node_by_name("Camera001.Target");
|
//view::state.eye = XMVector3Transform(XMVectorZero(), node_eye->world);
|
||||||
assert(node_at != 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,
|
||||||
@ -453,8 +456,13 @@ void update(float time)
|
|||||||
current_time = time;
|
current_time = time;
|
||||||
|
|
||||||
scene_state.update(time);
|
scene_state.update(time);
|
||||||
|
/*
|
||||||
view::state.eye = XMVector3Transform(XMVectorZero(), node_eye->world);
|
view::state.eye = XMVector3Transform(XMVectorZero(), node_eye->world);
|
||||||
view::state.at = XMVector3Transform(XMVectorZero(), node_at->world);
|
if (node_at == nullptr)
|
||||||
|
view::state.at = XMVectorZero();
|
||||||
|
else
|
||||||
|
view::state.at = XMVector3Transform(XMVectorZero(), node_at->world);
|
||||||
|
*/
|
||||||
|
|
||||||
view::update_transforms();
|
view::update_transforms();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -107,6 +107,6 @@ namespace view {
|
|||||||
//state.eye = XMVectorSet(-45.5f, 43.25f, 63.0f, 1);
|
//state.eye = XMVectorSet(-45.5f, 43.25f, 63.0f, 1);
|
||||||
//state.at = state.eye + state.direction * at_distance;
|
//state.at = state.eye + state.direction * at_distance;
|
||||||
state.at = XMVectorSet(0, 0, 0, 1);
|
state.at = XMVectorSet(0, 0, 0, 1);
|
||||||
state.eye = XMVectorSet(0, -10, 0, 1);
|
state.eye = XMVectorSet(0, -100, 0, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user