collada: draw animated joints
This commit is contained in:
parent
71744c4344
commit
f4e95aee09
@ -1,7 +1,7 @@
|
|||||||
set -eux
|
set -eux
|
||||||
|
|
||||||
PYTHONPATH=~/d3d10 python -m collada.main \
|
PYTHONPATH=~/d3d10 python -m collada.main \
|
||||||
path/to/noodle.DAE \
|
~/love-demo/scene/noodle/noodle.DAE \
|
||||||
data/scenes/noodle/noodle.cpp \
|
data/scenes/noodle/noodle.cpp \
|
||||||
data/scenes/noodle/noodle.vtx \
|
data/scenes/noodle/noodle.vtx \
|
||||||
data/scenes/noodle/noodle.vjw \
|
data/scenes/noodle/noodle.vjw \
|
||||||
|
|||||||
@ -1913,6 +1913,8 @@ channel const * const node_channels_node_environmentambientlight[] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
node const node_node_environmentambientlight = {
|
node const node_node_environmentambientlight = {
|
||||||
|
.name = "EnvironmentAmbientLight",
|
||||||
|
|
||||||
.parent_index = -1,
|
.parent_index = -1,
|
||||||
|
|
||||||
.type = node_type::NODE,
|
.type = node_type::NODE,
|
||||||
@ -1953,6 +1955,8 @@ channel const * const node_channels_node_cameratargethelper[] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
node const node_node_cameratargethelper = {
|
node const node_node_cameratargethelper = {
|
||||||
|
.name = "CameraTargetHelper",
|
||||||
|
|
||||||
.parent_index = -1,
|
.parent_index = -1,
|
||||||
|
|
||||||
.type = node_type::NODE,
|
.type = node_type::NODE,
|
||||||
@ -1993,6 +1997,8 @@ channel const * const node_channels_node_camera_target[] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
node const node_node_camera_target = {
|
node const node_node_camera_target = {
|
||||||
|
.name = "Camera.Target",
|
||||||
|
|
||||||
.parent_index = 1,
|
.parent_index = 1,
|
||||||
|
|
||||||
.type = node_type::NODE,
|
.type = node_type::NODE,
|
||||||
@ -2040,6 +2046,8 @@ channel const * const node_channels_node_omni001[] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
node const node_node_omni001 = {
|
node const node_node_omni001 = {
|
||||||
|
.name = "Omni001",
|
||||||
|
|
||||||
.parent_index = -1,
|
.parent_index = -1,
|
||||||
|
|
||||||
.type = node_type::NODE,
|
.type = node_type::NODE,
|
||||||
@ -2103,6 +2111,8 @@ channel const * const node_channels_node_box001[] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
node const node_node_box001 = {
|
node const node_node_box001 = {
|
||||||
|
.name = "Box001",
|
||||||
|
|
||||||
.parent_index = -1,
|
.parent_index = -1,
|
||||||
|
|
||||||
.type = node_type::NODE,
|
.type = node_type::NODE,
|
||||||
@ -2143,6 +2153,8 @@ channel const * const node_channels_node_bonehelper[] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
node const node_node_bonehelper = {
|
node const node_node_bonehelper = {
|
||||||
|
.name = "BoneHelper",
|
||||||
|
|
||||||
.parent_index = -1,
|
.parent_index = -1,
|
||||||
|
|
||||||
.type = node_type::NODE,
|
.type = node_type::NODE,
|
||||||
@ -2204,18 +2216,20 @@ instance_light const instance_lights_node_bone001[] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
channel const * const node_channels_node_bone001[] = {
|
channel const * const node_channels_node_bone001[] = {
|
||||||
&node_channel_node_bone001_translation_x,
|
|
||||||
&node_channel_node_bone001_translation_z,
|
|
||||||
&node_channel_node_bone001_scale,
|
|
||||||
&node_channel_node_bone001_translation_y,
|
|
||||||
&node_channel_node_bone001_rotationz_angle,
|
|
||||||
&node_channel_node_bone001_scaleaxisrotation,
|
|
||||||
&node_channel_node_bone001_rotationx_angle,
|
|
||||||
&node_channel_node_bone001_rotationy_angle,
|
&node_channel_node_bone001_rotationy_angle,
|
||||||
|
&node_channel_node_bone001_rotationz_angle,
|
||||||
|
&node_channel_node_bone001_translation_y,
|
||||||
|
&node_channel_node_bone001_translation_z,
|
||||||
|
&node_channel_node_bone001_rotationx_angle,
|
||||||
&node_channel_node_bone001_inversescaleaxisrotation,
|
&node_channel_node_bone001_inversescaleaxisrotation,
|
||||||
|
&node_channel_node_bone001_scale,
|
||||||
|
&node_channel_node_bone001_scaleaxisrotation,
|
||||||
|
&node_channel_node_bone001_translation_x,
|
||||||
};
|
};
|
||||||
|
|
||||||
node const node_node_bone001 = {
|
node const node_node_bone001 = {
|
||||||
|
.name = "Bone001",
|
||||||
|
|
||||||
.parent_index = 5,
|
.parent_index = 5,
|
||||||
|
|
||||||
.type = node_type::JOINT,
|
.type = node_type::JOINT,
|
||||||
@ -2277,18 +2291,20 @@ instance_light const instance_lights_node_bone002[] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
channel const * const node_channels_node_bone002[] = {
|
channel const * const node_channels_node_bone002[] = {
|
||||||
&node_channel_node_bone002_translation_x,
|
|
||||||
&node_channel_node_bone002_inversescaleaxisrotation,
|
|
||||||
&node_channel_node_bone002_translation_y,
|
&node_channel_node_bone002_translation_y,
|
||||||
&node_channel_node_bone002_scale,
|
&node_channel_node_bone002_scale,
|
||||||
&node_channel_node_bone002_rotationx_angle,
|
&node_channel_node_bone002_inversescaleaxisrotation,
|
||||||
&node_channel_node_bone002_rotationy_angle,
|
|
||||||
&node_channel_node_bone002_scaleaxisrotation,
|
&node_channel_node_bone002_scaleaxisrotation,
|
||||||
|
&node_channel_node_bone002_translation_x,
|
||||||
|
&node_channel_node_bone002_rotationy_angle,
|
||||||
&node_channel_node_bone002_rotationz_angle,
|
&node_channel_node_bone002_rotationz_angle,
|
||||||
|
&node_channel_node_bone002_rotationx_angle,
|
||||||
&node_channel_node_bone002_translation_z,
|
&node_channel_node_bone002_translation_z,
|
||||||
};
|
};
|
||||||
|
|
||||||
node const node_node_bone002 = {
|
node const node_node_bone002 = {
|
||||||
|
.name = "Bone002",
|
||||||
|
|
||||||
.parent_index = 6,
|
.parent_index = 6,
|
||||||
|
|
||||||
.type = node_type::JOINT,
|
.type = node_type::JOINT,
|
||||||
@ -2350,18 +2366,20 @@ instance_light const instance_lights_node_bone003[] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
channel const * const node_channels_node_bone003[] = {
|
channel const * const node_channels_node_bone003[] = {
|
||||||
&node_channel_node_bone003_translation_y,
|
|
||||||
&node_channel_node_bone003_rotationy_angle,
|
|
||||||
&node_channel_node_bone003_translation_x,
|
|
||||||
&node_channel_node_bone003_rotationz_angle,
|
|
||||||
&node_channel_node_bone003_inversescaleaxisrotation,
|
|
||||||
&node_channel_node_bone003_rotationx_angle,
|
|
||||||
&node_channel_node_bone003_translation_z,
|
|
||||||
&node_channel_node_bone003_scaleaxisrotation,
|
|
||||||
&node_channel_node_bone003_scale,
|
&node_channel_node_bone003_scale,
|
||||||
|
&node_channel_node_bone003_rotationz_angle,
|
||||||
|
&node_channel_node_bone003_rotationy_angle,
|
||||||
|
&node_channel_node_bone003_rotationx_angle,
|
||||||
|
&node_channel_node_bone003_scaleaxisrotation,
|
||||||
|
&node_channel_node_bone003_translation_y,
|
||||||
|
&node_channel_node_bone003_inversescaleaxisrotation,
|
||||||
|
&node_channel_node_bone003_translation_z,
|
||||||
|
&node_channel_node_bone003_translation_x,
|
||||||
};
|
};
|
||||||
|
|
||||||
node const node_node_bone003 = {
|
node const node_node_bone003 = {
|
||||||
|
.name = "Bone003",
|
||||||
|
|
||||||
.parent_index = 7,
|
.parent_index = 7,
|
||||||
|
|
||||||
.type = node_type::JOINT,
|
.type = node_type::JOINT,
|
||||||
@ -2402,6 +2420,8 @@ channel const * const node_channels_node_camerahelper_1[] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
node const node_node_camerahelper_1 = {
|
node const node_node_camerahelper_1 = {
|
||||||
|
.name = "CameraHelper",
|
||||||
|
|
||||||
.parent_index = -1,
|
.parent_index = -1,
|
||||||
|
|
||||||
.type = node_type::NODE,
|
.type = node_type::NODE,
|
||||||
@ -2442,6 +2462,8 @@ channel const * const node_channels_node_camera001[] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
node const node_node_camera001 = {
|
node const node_node_camera001 = {
|
||||||
|
.name = "Camera001",
|
||||||
|
|
||||||
.parent_index = 9,
|
.parent_index = 9,
|
||||||
|
|
||||||
.type = node_type::NODE,
|
.type = node_type::NODE,
|
||||||
@ -2482,6 +2504,8 @@ channel const * const node_channels_node_cameratargethelper_1[] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
node const node_node_cameratargethelper_1 = {
|
node const node_node_cameratargethelper_1 = {
|
||||||
|
.name = "CameraTargetHelper",
|
||||||
|
|
||||||
.parent_index = -1,
|
.parent_index = -1,
|
||||||
|
|
||||||
.type = node_type::NODE,
|
.type = node_type::NODE,
|
||||||
@ -2522,6 +2546,8 @@ channel const * const node_channels_node_camera001_target[] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
node const node_node_camera001_target = {
|
node const node_node_camera001_target = {
|
||||||
|
.name = "Camera001.Target",
|
||||||
|
|
||||||
.parent_index = 11,
|
.parent_index = 11,
|
||||||
|
|
||||||
.type = node_type::NODE,
|
.type = node_type::NODE,
|
||||||
|
|||||||
@ -17,6 +17,7 @@ namespace collada::scene {
|
|||||||
unsigned int vertex_buffer_pnt;
|
unsigned int vertex_buffer_pnt;
|
||||||
unsigned int vertex_buffer_jw;
|
unsigned int vertex_buffer_jw;
|
||||||
unsigned int index_buffer;
|
unsigned int index_buffer;
|
||||||
|
unsigned int joint_uniform_buffer;
|
||||||
|
|
||||||
static_skinned * vertex_arrays;
|
static_skinned * vertex_arrays;
|
||||||
int * vertex_buffer_strides_pnt;
|
int * vertex_buffer_strides_pnt;
|
||||||
|
|||||||
@ -3,9 +3,16 @@
|
|||||||
layout (location = 0) in vec3 Position;
|
layout (location = 0) in vec3 Position;
|
||||||
layout (location = 1) in vec3 Normal;
|
layout (location = 1) in vec3 Normal;
|
||||||
layout (location = 2) in vec2 Texture;
|
layout (location = 2) in vec2 Texture;
|
||||||
|
layout (location = 3) in ivec4 BlendIndices;
|
||||||
|
layout (location = 4) in vec4 BlendWeight;
|
||||||
|
|
||||||
layout (location = 0) uniform mat4 Transform;
|
layout (location = 0) uniform mat4 Transform;
|
||||||
|
|
||||||
|
layout (std140, binding = 0) uniform JointsLayout
|
||||||
|
{
|
||||||
|
mat4 Joints[64];
|
||||||
|
};
|
||||||
|
|
||||||
out vec3 PixelNormal;
|
out vec3 PixelNormal;
|
||||||
out vec2 PixelTexture;
|
out vec2 PixelTexture;
|
||||||
|
|
||||||
@ -14,5 +21,14 @@ void main()
|
|||||||
PixelNormal = Normal;
|
PixelNormal = Normal;
|
||||||
PixelTexture = vec2(Texture.x, 1.0 - Texture.y);
|
PixelTexture = vec2(Texture.x, 1.0 - Texture.y);
|
||||||
|
|
||||||
gl_Position = Transform * vec4(Position, 1);
|
mat4 skin
|
||||||
|
= BlendWeight.x * Joints[BlendIndices.x]
|
||||||
|
+ BlendWeight.y * Joints[BlendIndices.y]
|
||||||
|
+ BlendWeight.z * Joints[BlendIndices.z]
|
||||||
|
+ BlendWeight.w * Joints[BlendIndices.w]
|
||||||
|
;
|
||||||
|
|
||||||
|
vec4 position = skin * vec4(Position, 1);
|
||||||
|
|
||||||
|
gl_Position = Transform * position;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -80,7 +80,9 @@ namespace collada::node_state {
|
|||||||
case types::transform_type::TRANSLATE:
|
case types::transform_type::TRANSLATE:
|
||||||
return XMMatrixTranslationFromVector(transform.vector);
|
return XMMatrixTranslationFromVector(transform.vector);
|
||||||
case types::transform_type::ROTATE:
|
case types::transform_type::ROTATE:
|
||||||
assert(!vector_equal(XMVectorSetW(transform.vector, 0), XMVectorZero()));
|
//assert(!vector_equal(XMVectorSetW(transform.vector, 0), XMVectorZero()));
|
||||||
|
if (vector_equal(XMVectorSetW(transform.vector, 0), XMVectorZero()))
|
||||||
|
return XMMatrixIdentity();
|
||||||
return XMMatrixRotationNormal(transform.vector,
|
return XMMatrixRotationNormal(transform.vector,
|
||||||
XMConvertToRadians(XMVectorGetW(transform.vector)));
|
XMConvertToRadians(XMVectorGetW(transform.vector)));
|
||||||
case types::transform_type::SCALE:
|
case types::transform_type::SCALE:
|
||||||
|
|||||||
@ -50,6 +50,9 @@ namespace collada::scene {
|
|||||||
unsigned int diffuse;
|
unsigned int diffuse;
|
||||||
unsigned int specular;
|
unsigned int specular;
|
||||||
} texture_unit;
|
} texture_unit;
|
||||||
|
struct {
|
||||||
|
unsigned int joint;
|
||||||
|
} binding;
|
||||||
};
|
};
|
||||||
|
|
||||||
const layout layout = {
|
const layout layout = {
|
||||||
@ -84,6 +87,9 @@ namespace collada::scene {
|
|||||||
.diffuse = GL_TEXTURE2,
|
.diffuse = GL_TEXTURE2,
|
||||||
.specular = GL_TEXTURE3,
|
.specular = GL_TEXTURE3,
|
||||||
},
|
},
|
||||||
|
.binding {
|
||||||
|
.joint = 0,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
unsigned int attribute_location(char const * const semantic,
|
unsigned int attribute_location(char const * const semantic,
|
||||||
@ -151,7 +157,11 @@ namespace collada::scene {
|
|||||||
glEnableVertexAttribArray(location);
|
glEnableVertexAttribArray(location);
|
||||||
unsigned int gl_size = input_format_gl_size(inputs.elements[i].format);
|
unsigned int gl_size = input_format_gl_size(inputs.elements[i].format);
|
||||||
unsigned int gl_type = input_format_gl_type(inputs.elements[i].format);
|
unsigned int gl_type = input_format_gl_type(inputs.elements[i].format);
|
||||||
glVertexAttribFormat(location, gl_size, gl_type, GL_FALSE, offset);
|
if (gl_type == GL_INT) {
|
||||||
|
glVertexAttribIFormat(location, gl_size, gl_type, offset);
|
||||||
|
} else {
|
||||||
|
glVertexAttribFormat(location, gl_size, gl_type, GL_FALSE, offset);
|
||||||
|
}
|
||||||
glVertexAttribBinding(location, binding);
|
glVertexAttribBinding(location, binding);
|
||||||
offset += gl_size * 4;
|
offset += gl_size * 4;
|
||||||
}
|
}
|
||||||
@ -179,8 +189,8 @@ namespace collada::scene {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const int vertex_buffer_stride_jw
|
const int vertex_buffer_stride_jw
|
||||||
= input_format_gl_size(skin_inputs.elements[0].format)
|
= 4 * input_format_gl_size(skin_inputs.elements[0].format)
|
||||||
+ input_format_gl_size(skin_inputs.elements[1].format);
|
+ 4 * input_format_gl_size(skin_inputs.elements[1].format);
|
||||||
|
|
||||||
void state::load_layouts()
|
void state::load_layouts()
|
||||||
{
|
{
|
||||||
@ -209,7 +219,7 @@ namespace collada::scene {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int load_vertex_buffer(const char * filename)
|
static unsigned int load_vertex_buffer(const char * filename)
|
||||||
{
|
{
|
||||||
int size;
|
int size;
|
||||||
void * data = read_file(filename, &size);
|
void * data = read_file(filename, &size);
|
||||||
@ -226,7 +236,7 @@ namespace collada::scene {
|
|||||||
return vertex_buffer;
|
return vertex_buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int load_index_buffer(const char * filename)
|
static unsigned int load_index_buffer(const char * filename)
|
||||||
{
|
{
|
||||||
int size;
|
int size;
|
||||||
void * data = read_file(filename, &size);
|
void * data = read_file(filename, &size);
|
||||||
@ -265,6 +275,13 @@ namespace collada::scene {
|
|||||||
glBindTexture(GL_TEXTURE_2D, 0);
|
glBindTexture(GL_TEXTURE_2D, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static unsigned int load_uniform_buffer()
|
||||||
|
{
|
||||||
|
unsigned int buffer;
|
||||||
|
glGenBuffers(1, &buffer);
|
||||||
|
return buffer;
|
||||||
|
}
|
||||||
|
|
||||||
void state::load_scene(types::descriptor const * const descriptor)
|
void state::load_scene(types::descriptor const * const descriptor)
|
||||||
{
|
{
|
||||||
this->descriptor = descriptor;
|
this->descriptor = descriptor;
|
||||||
@ -274,6 +291,7 @@ namespace collada::scene {
|
|||||||
vertex_buffer_pnt = load_vertex_buffer(descriptor->position_normal_texture_buffer);
|
vertex_buffer_pnt = load_vertex_buffer(descriptor->position_normal_texture_buffer);
|
||||||
vertex_buffer_jw = load_vertex_buffer(descriptor->joint_weight_buffer);
|
vertex_buffer_jw = load_vertex_buffer(descriptor->joint_weight_buffer);
|
||||||
index_buffer = load_index_buffer(descriptor->index_buffer);
|
index_buffer = load_index_buffer(descriptor->index_buffer);
|
||||||
|
joint_uniform_buffer = load_uniform_buffer();
|
||||||
|
|
||||||
load_images();
|
load_images();
|
||||||
|
|
||||||
@ -432,6 +450,21 @@ 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;
|
||||||
|
|
||||||
|
XMFLOAT4X4 joints[instance_controller.joint_count];
|
||||||
|
int joints_size = (sizeof (joints));
|
||||||
|
for (int joint_index = 0; joint_index < instance_controller.joint_count; joint_index++) {
|
||||||
|
XMMATRIX ibm = XMLoadFloat4x4((XMFLOAT4X4*)&skin.inverse_bind_matrices[joint_index]);
|
||||||
|
int node_index = instance_controller.joint_node_indices[joint_index];
|
||||||
|
instance_types::node& node_instance = node_state.node_instances[node_index];
|
||||||
|
|
||||||
|
XMStoreFloat4x4(&joints[joint_index], ibm * node_instance.world);
|
||||||
|
}
|
||||||
|
glBindBuffer(GL_UNIFORM_BUFFER, joint_uniform_buffer);
|
||||||
|
glBufferData(GL_UNIFORM_BUFFER, joints_size, (void *)&joints[0], GL_DYNAMIC_DRAW);
|
||||||
|
glBindBuffer(GL_UNIFORM_BUFFER, 0);
|
||||||
|
|
||||||
|
glBindBufferRange(GL_UNIFORM_BUFFER, layout.binding.joint, joint_uniform_buffer, 0, joints_size);
|
||||||
|
|
||||||
draw_skin(skin,
|
draw_skin(skin,
|
||||||
instance_controller.instance_materials,
|
instance_controller.instance_materials,
|
||||||
instance_controller.instance_materials_count);
|
instance_controller.instance_materials_count);
|
||||||
@ -451,7 +484,7 @@ namespace collada::scene {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (node.instance_controllers_count) {
|
if (node.instance_controllers_count) {
|
||||||
glUseProgram(collada::effect::program_static);
|
glUseProgram(collada::effect::program_skinned);
|
||||||
glUniformMatrix4fv(layout.uniform.transform, 1, false, (float *)&float_transform);
|
glUniformMatrix4fv(layout.uniform.transform, 1, false, (float *)&float_transform);
|
||||||
draw_instance_controllers(node.instance_controllers, node.instance_controllers_count);
|
draw_instance_controllers(node.instance_controllers, node.instance_controllers_count);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -309,7 +309,7 @@ void load(const char * source_path)
|
|||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
collada::effect::load_effects();
|
collada::effect::load_effects();
|
||||||
scene_state.load_scene(&shadow_test::descriptor);
|
scene_state.load_scene(&noodle::descriptor);
|
||||||
node_eye = scene_state.find_node_by_name("Camera001");
|
node_eye = scene_state.find_node_by_name("Camera001");
|
||||||
assert(node_eye != nullptr);
|
assert(node_eye != nullptr);
|
||||||
node_at = scene_state.find_node_by_name("Camera001.Target");
|
node_at = scene_state.find_node_by_name("Camera001.Target");
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user