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/effect.o \
|
||||
src/collada/node_state.o \
|
||||
src/collada/animate.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
|
||||
|
||||
|
||||
@ -9,3 +9,15 @@ PYTHONPATH=~/d3d10 python -m collada.main \
|
||||
|
||||
PYTHONPATH=~/d3d10 python -m collada.main \
|
||||
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;
|
||||
};
|
||||
|
||||
struct node_instance {
|
||||
transform * transforms = NULL;
|
||||
struct node {
|
||||
// immutable state
|
||||
types::node const * node;
|
||||
|
||||
// mutable state
|
||||
transform * transforms;
|
||||
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
|
||||
|
||||
#include "collada/types.h"
|
||||
#include "collada/instance_types.h"
|
||||
#include "collada/node_state.h"
|
||||
|
||||
namespace collada::scene {
|
||||
struct static_skinned {
|
||||
@ -10,6 +12,7 @@ namespace collada::scene {
|
||||
|
||||
struct state {
|
||||
types::descriptor const * descriptor;
|
||||
node_state::state node_state;
|
||||
|
||||
unsigned int vertex_buffer_pnt;
|
||||
unsigned int vertex_buffer_jw;
|
||||
@ -20,6 +23,7 @@ namespace collada::scene {
|
||||
|
||||
unsigned int * textures;
|
||||
|
||||
// drawing
|
||||
void load_layouts();
|
||||
void load_images();
|
||||
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,
|
||||
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();
|
||||
|
||||
// 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 {
|
||||
char const * name;
|
||||
|
||||
int const parent_index;
|
||||
|
||||
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)
|
||||
{
|
||||
return f - floorf(f);
|
||||
}
|
||||
#include <stdio.h>
|
||||
|
||||
static inline float loop(float f, float n)
|
||||
{
|
||||
return fract(f / n) * n;
|
||||
}
|
||||
#include "directxmath/directxmath.h"
|
||||
|
||||
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++) {
|
||||
if (source.float_array[i] <= t && source.float_array[i+1] > t) {
|
||||
@ -18,14 +17,14 @@
|
||||
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 next = source.float_array[(frame_ix+1) * source.stride];
|
||||
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 next = source.float_array[(frame_ix+1) * source.stride + parameter_ix];
|
||||
@ -76,20 +75,20 @@
|
||||
}
|
||||
}
|
||||
|
||||
print("%f %f\n", XMVectorGetX(p0), XMVectorGetY(p0));
|
||||
print("%f %f\n", XMVectorGetX(c0), XMVectorGetY(c0));
|
||||
print("%f %f\n", XMVectorGetX(c1), XMVectorGetY(c1));
|
||||
print("%f %f\n", XMVectorGetX(p1), XMVectorGetY(p1));
|
||||
fprintf(stderr, "%f %f\n", XMVectorGetX(p0), XMVectorGetY(p0));
|
||||
fprintf(stderr, "%f %f\n", XMVectorGetX(c0), XMVectorGetY(c0));
|
||||
fprintf(stderr, "%f %f\n", XMVectorGetX(c1), XMVectorGetY(c1));
|
||||
fprintf(stderr, "%f %f\n", XMVectorGetX(p1), XMVectorGetY(p1));
|
||||
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;
|
||||
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])
|
||||
@ -112,25 +111,25 @@
|
||||
return bezier_binary_search(p0, c0, c1, p1, t);
|
||||
}
|
||||
|
||||
static void apply_transform_target(transform& transform,
|
||||
enum target_attribute channel_target_attribute,
|
||||
static void apply_transform_target(instance_types::transform& transform,
|
||||
enum types::target_attribute channel_target_attribute,
|
||||
float value)
|
||||
{
|
||||
switch (transform.type) {
|
||||
case transform_type::TRANSLATE: __attribute__((fallthrough));
|
||||
case transform_type::SCALE:
|
||||
case types::transform_type::TRANSLATE: __attribute__((fallthrough));
|
||||
case types::transform_type::SCALE:
|
||||
switch (channel_target_attribute) {
|
||||
case target_attribute::X: transform.vector = XMVectorSetX(transform.vector, value); return;
|
||||
case 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::X: transform.vector = XMVectorSetX(transform.vector, value); return;
|
||||
case types::target_attribute::Y: transform.vector = XMVectorSetY(transform.vector, value); return;
|
||||
case types::target_attribute::Z: transform.vector = XMVectorSetZ(transform.vector, value); return;
|
||||
default: assert(false);
|
||||
}
|
||||
case transform_type::ROTATE:
|
||||
case types::transform_type::ROTATE:
|
||||
switch (channel_target_attribute) {
|
||||
case target_attribute::X: transform.vector = XMVectorSetX(transform.vector, value); return;
|
||||
case target_attribute::Y: transform.vector = XMVectorSetY(transform.vector, value); return;
|
||||
case 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::X: transform.vector = XMVectorSetX(transform.vector, value); return;
|
||||
case types::target_attribute::Y: transform.vector = XMVectorSetY(transform.vector, value); return;
|
||||
case types::target_attribute::Z: transform.vector = XMVectorSetZ(transform.vector, value); return;
|
||||
case types::target_attribute::ANGLE: transform.vector = XMVectorSetW(transform.vector, value); return;
|
||||
default: assert(false);
|
||||
}
|
||||
default:
|
||||
@ -139,33 +138,33 @@
|
||||
}
|
||||
}
|
||||
|
||||
static enum target_attribute const rotate_target_attributes[] = {
|
||||
target_attribute::X,
|
||||
target_attribute::Y,
|
||||
target_attribute::Z,
|
||||
target_attribute::ANGLE,
|
||||
static enum types::target_attribute const rotate_target_attributes[] = {
|
||||
types::target_attribute::X,
|
||||
types::target_attribute::Y,
|
||||
types::target_attribute::Z,
|
||||
types::target_attribute::ANGLE,
|
||||
};
|
||||
|
||||
static enum target_attribute const translate_scale_target_attributes[] = {
|
||||
target_attribute::X,
|
||||
target_attribute::Y,
|
||||
target_attribute::Z,
|
||||
static enum types::target_attribute const translate_scale_target_attributes[] = {
|
||||
types::target_attribute::X,
|
||||
types::target_attribute::Y,
|
||||
types::target_attribute::Z,
|
||||
};
|
||||
|
||||
static void animate_channel_segment(channel const& channel,
|
||||
transform& transform,
|
||||
static void animate_channel_segment(types::channel const& channel,
|
||||
instance_types::transform& transform,
|
||||
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;
|
||||
if (channel.target_attribute == target_attribute::ALL) {
|
||||
if (channel.target_attribute == types::target_attribute::ALL) {
|
||||
switch (transform.type) {
|
||||
case transform_type::TRANSLATE: __attribute__((fallthrough));
|
||||
case transform_type::SCALE:
|
||||
case types::transform_type::TRANSLATE: __attribute__((fallthrough));
|
||||
case types::transform_type::SCALE:
|
||||
target_attributes = translate_scale_target_attributes;
|
||||
target_attributes_count = 3;
|
||||
break;
|
||||
case transform_type::ROTATE:
|
||||
case types::transform_type::ROTATE:
|
||||
target_attributes = rotate_target_attributes;
|
||||
target_attributes_count = 4;
|
||||
break;
|
||||
@ -177,10 +176,10 @@
|
||||
|
||||
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;
|
||||
if (interpolation == interpolation::BEZIER) {
|
||||
if (interpolation == types::interpolation::BEZIER) {
|
||||
value = bezier_sampler(channel.source_sampler, frame_ix, parameter_ix, t);
|
||||
} else {
|
||||
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++) {
|
||||
channel const& channel = *node.channels[i];
|
||||
transform& transform = node_instance.transforms[channel.target_transform_index];
|
||||
for (int i = 0; i < node_instance.node->channels_count; i++) {
|
||||
types::channel const& channel = *node_instance.node->channels[i];
|
||||
instance_types::transform& transform = node_instance.transforms[channel.target_transform_index];
|
||||
|
||||
int frame_ix = find_frame_ix(channel.source_sampler->input, t);
|
||||
assert(frame_ix >= 0); // animation is missing a key frame
|
||||
@ -203,3 +202,4 @@
|
||||
animate_channel_segment(channel, transform, frame_ix, t);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,11 +1,19 @@
|
||||
#include <stdio.h>
|
||||
|
||||
#include "directxmath/directxmath.h"
|
||||
|
||||
#include "collada/types.h"
|
||||
#include "collada/instance_types.h"
|
||||
#include "new.h"
|
||||
|
||||
#include "collada/node_state.h"
|
||||
|
||||
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) {
|
||||
case types::transform_type::LOOKAT:
|
||||
@ -28,17 +36,37 @@ namespace collada::node_state {
|
||||
default:
|
||||
assert(false);
|
||||
}
|
||||
instance_transform->type = transform.type;
|
||||
}
|
||||
|
||||
void initialize_node_transforms(types::node const * const node,
|
||||
instance_types::node_instance * const node_instance)
|
||||
inline static void initialize_node_transforms(instance_types::node & node_instance)
|
||||
{
|
||||
for (int i = 0; i < node->transforms_count; i++) {
|
||||
load_transform(&node_instance->transforms[i],
|
||||
node->transforms[i]);
|
||||
for (int i = 0; i < node_instance.node->transforms_count; i++) {
|
||||
load_transform(node_instance.node->transforms[i], &node_instance.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)
|
||||
{
|
||||
uint32_t CR;
|
||||
@ -60,8 +88,25 @@ namespace collada::node_state {
|
||||
case types::transform_type::MATRIX:
|
||||
return transform.matrix;
|
||||
default:
|
||||
fprintf(stderr, "unknown transform type %d\n", (int)transform.type);
|
||||
assert(false);
|
||||
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/scene.h"
|
||||
#include "collada/effect.h"
|
||||
#include "collada/animate.h"
|
||||
|
||||
namespace collada::scene {
|
||||
|
||||
@ -275,6 +276,8 @@ namespace collada::scene {
|
||||
index_buffer = load_index_buffer(descriptor->index_buffer);
|
||||
|
||||
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,
|
||||
@ -337,8 +340,6 @@ namespace collada::scene {
|
||||
types::instance_material const * const instance_materials,
|
||||
int const instance_materials_count)
|
||||
{
|
||||
glUseProgram(collada::effect::program_static);
|
||||
|
||||
types::mesh const& mesh = geometry.mesh;
|
||||
|
||||
for (int j = 0; j < instance_materials_count; j++) {
|
||||
@ -437,18 +438,30 @@ 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)
|
||||
{
|
||||
XMMATRIX transform = node_instance.world * view::state.transform;
|
||||
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()
|
||||
{
|
||||
unsigned int effects[] = {collada::effect::program_static, collada::effect::program_skinned};
|
||||
for (int i = 0; i < 2; i++) {
|
||||
glUseProgram(effects[i]);
|
||||
glUniformMatrix4fv(layout.uniform.transform, 1, false, (float *)&view::state.float_transform);
|
||||
glUniform1i(layout.uniform.emission_sampler, 0);
|
||||
glUniform1i(layout.uniform.ambient_sampler, 1);
|
||||
glUniform1i(layout.uniform.diffuse_sampler, 2);
|
||||
@ -468,7 +481,27 @@ namespace collada::scene {
|
||||
if (node.type != types::node_type::NODE)
|
||||
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/scene.h"
|
||||
#include "collada/types.h"
|
||||
#include "collada/instance_types.h"
|
||||
|
||||
#include "data/scenes/ship20.h"
|
||||
#include "data/scenes/noodle.h"
|
||||
#include "data/scenes/shadow_test.h"
|
||||
|
||||
struct line_location {
|
||||
struct {
|
||||
@ -73,6 +75,9 @@ static target_type const geometry_buffer_pnc_types[3] = {
|
||||
[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()
|
||||
{
|
||||
uint8_t const data[] = {
|
||||
@ -304,7 +309,11 @@ void load(const char * source_path)
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
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,
|
||||
@ -416,8 +425,11 @@ void update_joystick(int joystick_index,
|
||||
}
|
||||
*/
|
||||
|
||||
view::state.at = view::state.at + direction;
|
||||
view::state.eye = view::state.at - view::state.direction * view::at_distance;
|
||||
view::state.eye = view::state.eye + direction;
|
||||
//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;
|
||||
@ -440,6 +452,10 @@ void update(float 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();
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user