collada: animate eidelwind walking inside grandlecturn

This commit is contained in:
Zack Buhman 2026-03-31 20:10:35 -05:00
parent 5724fde489
commit e98e45beac
10 changed files with 175 additions and 77 deletions

View File

@ -84,7 +84,7 @@ all: main
$(CXX) $(ARCH) $(CXXSTD) $(CFLAGS) $(OPT) $(DEBUG) -c $< -o $@
PACK_FILENAMES = $(shell cat filenames.txt)
test.pack: tool/pack_file $(PACK_FILENAMES)
test.pack: tool/pack_file $(PACK_FILENAMES) filenames.txt
./tool/pack_file $@ $(PACK_FILENAMES)
test.pack.o: test.pack

View File

@ -1,56 +1,53 @@
shader/minecraft.vert
shader/minecraft.frag
minecraft/per_vertex.vtx
minecraft/configuration.idx
minecraft/terrain2.data
minecraft/grandlecturn/region.0.0.instance.vtx
minecraft/grandlecturn/region.0.0.instance.cfg
minecraft/grandlecturn/region.-1.0.instance.vtx
minecraft/grandlecturn/region.-1.0.instance.cfg
minecraft/grandlecturn/region.0.-1.instance.vtx
minecraft/grandlecturn/region.0.-1.instance.cfg
minecraft/grandlecturn/region.-1.-1.instance.vtx
minecraft/grandlecturn/region.-1.-1.instance.cfg
minecraft/grandlecturn/global.lights.vtx
minecraft/grandlecturn/global.dump
minecraft/midnightmeadow/region.0.0.instance.vtx
minecraft/midnightmeadow/region.0.0.instance.cfg
minecraft/midnightmeadow/region.-1.0.instance.vtx
minecraft/midnightmeadow/region.-1.0.instance.cfg
minecraft/midnightmeadow/region.0.-1.instance.vtx
minecraft/midnightmeadow/region.0.-1.instance.cfg
minecraft/midnightmeadow/region.-1.-1.instance.vtx
minecraft/midnightmeadow/region.-1.-1.instance.cfg
minecraft/midnightmeadow/global.lights.vtx
minecraft/midnightmeadow/global.dump
shader/font.vert
shader/font.frag
font/bitmap/terminus_128x64_6x12.data
data/scenes/eidelwind/images/0_map_face_only.dds
data/scenes/eidelwind/scene.idx
data/scenes/eidelwind/scene.vjw
data/scenes/eidelwind/scene.vtx
font/bitmap/terminus_128x128_8x16.data
font/bitmap/terminus_128x64_6x12.data
font/bitmap/terminus_256x128_10x18.data
font/bitmap/terminus_256x128_12x24.data
font/bitmap/terminus_256x256_16x32.data
shader/font.vert
shader/font_outline.frag
font/outline/uncial_antiqua_36.data
shader/quad.vert
shader/quad.frag
shader/quad.vert
shader/lighting.frag
shader/non_block.vert
shader/non_block.frag
minecraft/configuration.idx
minecraft/flame.data
minecraft/grandlecturn/global.dump
minecraft/grandlecturn/global.lights.vtx
minecraft/grandlecturn/region.0.0.instance.cfg
minecraft/grandlecturn/region.0.0.instance.vtx
minecraft/grandlecturn/region.0.-1.instance.cfg
minecraft/grandlecturn/region.0.-1.instance.vtx
minecraft/grandlecturn/region.-1.0.instance.cfg
minecraft/grandlecturn/region.-1.0.instance.vtx
minecraft/grandlecturn/region.-1.-1.instance.cfg
minecraft/grandlecturn/region.-1.-1.instance.vtx
minecraft/midnightmeadow/global.dump
minecraft/midnightmeadow/global.lights.vtx
minecraft/midnightmeadow/region.0.0.instance.cfg
minecraft/midnightmeadow/region.0.0.instance.vtx
minecraft/midnightmeadow/region.0.-1.instance.cfg
minecraft/midnightmeadow/region.0.-1.instance.vtx
minecraft/midnightmeadow/region.-1.0.instance.cfg
minecraft/midnightmeadow/region.-1.0.instance.vtx
minecraft/midnightmeadow/region.-1.-1.instance.cfg
minecraft/midnightmeadow/region.-1.-1.instance.vtx
minecraft/non_block.idx
minecraft/non_block.vtx
shader/line_art.vert
shader/line_art.frag
shader/collada/static.vert
shader/collada/generic.frag
minecraft/per_vertex.vtx
minecraft/terrain2.data
shader/collada/generic_geometry.frag
shader/collada/skinned.vert
shader/collada/generic.frag
data/scenes/eidelwind/scene.vtx
data/scenes/eidelwind/scene.vjw
data/scenes/eidelwind/scene.idx
data/scenes/eidelwind/images/0_map_face_only.dds
shader/flame.vert
shader/collada/static.vert
shader/flame.frag
minecraft/flame.data
shader/flame.vert
shader/font.frag
shader/font_outline.frag
shader/font.vert
shader/lighting.frag
shader/line_art.frag
shader/line_art.vert
shader/minecraft.frag
shader/minecraft.vert
shader/non_block.frag
shader/non_block.vert
shader/quad.frag
shader/quad.vert

View File

@ -48,8 +48,8 @@ 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, instance_types::node const & node_instance);
void draw();
void draw_node(XMMATRIX const & ext_transform, types::node const & node, instance_types::node const & node_instance);
void draw(XMMATRIX const & ext_transform);
// state updates
void update(float t);

View File

@ -0,0 +1,64 @@
#version 430 core
in VS_OUT {
vec3 Position; // world coordinates
vec3 Normal;
vec2 Texture;
} fs_in;
layout (location = 10) uniform vec4 EmissionColor;
layout (location = 11) uniform vec4 AmbientColor;
layout (location = 12) uniform vec4 DiffuseColor;
layout (location = 13) uniform vec4 SpecularColor;
layout (location = 14) uniform float shininess;
layout (location = 15) uniform sampler2D EmissionSampler;
layout (location = 16) uniform sampler2D AmbientSampler;
layout (location = 17) uniform sampler2D DiffuseSampler;
layout (location = 18) uniform sampler2D SpecularSampler;
layout (location = 19) uniform ivec4 TextureChannel;
layout (location = 0) out vec4 Position;
layout (location = 1) out vec4 Normal;
layout (location = 2) out vec4 Color;
layout (location = 3) out vec4 Block;
void main()
{
vec4 emission;
vec4 ambient;
vec4 diffuse;
vec4 specular;
if (TextureChannel.x >= 0) { // emission
emission = texture(EmissionSampler, fs_in.Texture.xy);
} else {
emission = EmissionColor;
}
if (TextureChannel.y >= 0) { // ambient
ambient = texture(AmbientSampler, fs_in.Texture.xy);
} else {
ambient = AmbientColor;
}
if (TextureChannel.z >= 0) { // diffuse
diffuse = texture(DiffuseSampler, fs_in.Texture.xy);
} else {
diffuse = DiffuseColor;
}
if (TextureChannel.w >= 0) { // specular
specular = texture(SpecularSampler, fs_in.Texture.xy);
} else {
specular = SpecularColor;
}
vec3 color = emission.xyz * 0;
color += ambient.xyz * 0.05;
color += diffuse.xyz * 1;
color += specular.xyz * 0 * 0.3;
Position = vec4(fs_in.Position, 1.0);
Normal = vec4(fs_in.Normal, 0.0);
Color = vec4(color, 1.0);
Block = vec4(0, 0, 0, 0);
}

View File

@ -7,20 +7,21 @@ layout (location = 3) in ivec4 BlendIndices;
layout (location = 4) in vec4 BlendWeight;
layout (location = 0) uniform mat4 Transform;
layout (location = 1) uniform mat4 WorldTransform;
layout (std140, binding = 0) uniform JointsLayout
{
mat4 Joints[64];
};
out vec3 PixelNormal;
out vec2 PixelTexture;
out VS_OUT {
vec3 Position;
vec3 Normal;
vec2 Texture;
} vs_out;
void main()
{
PixelNormal = Normal;
PixelTexture = vec2(Texture.x, 1.0 - Texture.y);
mat4 skin
= BlendWeight.x * Joints[BlendIndices.x]
+ BlendWeight.y * Joints[BlendIndices.y]
@ -30,5 +31,9 @@ void main()
vec4 position = skin * vec4(Position, 1);
vs_out.Position = (WorldTransform * position).xyz;
vs_out.Normal = Normal;
vs_out.Texture = vec2(Texture.x, 1.0 - Texture.y);
gl_Position = Transform * position;
}

View File

@ -5,14 +5,19 @@ layout (location = 1) in vec3 Normal;
layout (location = 2) in vec2 Texture;
layout (location = 0) uniform mat4 Transform;
layout (location = 1) uniform mat4 WorldTransform;
out vec3 PixelNormal;
out vec2 PixelTexture;
out VS_OUT {
vec3 Position;
vec3 Normal;
vec2 Texture;
} vs_out;
void main()
{
PixelNormal = Normal;
PixelTexture = vec2(Texture.x, 1.0 - Texture.y);
vs_out.Position = Position;
vs_out.Normal = Normal;
vs_out.Texture = vec2(Texture.x, 1.0 - Texture.y);
gl_Position = Transform * vec4(Position, 1);
}

View File

@ -29,7 +29,7 @@ void main()
if (LightCount != 0) {
for (int i = 0; i < LightCount; i++) {
vec3 light_position = light[i].xzy + vec3(0, 0, 0.5);
float light_distance = length(light_position - position.xyz);
float light_distance = length(light_position - position.xyz) * 0.5;
vec3 light_direction = normalize(light_position - position.xyz);
float diffuse = max(dot(normal.xyz, light_direction), 0.0);
if (normal.w == 1.0) // two-sided

View File

@ -11,10 +11,10 @@ namespace collada::effect {
{
program_static = compile_from_files("shader/collada/static.vert",
nullptr,
"shader/collada/generic.frag");
"shader/collada/generic_geometry.frag");
program_skinned = compile_from_files("shader/collada/skinned.vert",
nullptr,
"shader/collada/generic.frag");
"shader/collada/generic_geometry.frag");
}
}

View File

@ -29,6 +29,7 @@ namespace collada::scene {
struct {
// vertex
unsigned int transform;
unsigned int world_transform;
// fragment
unsigned int emission_color;
unsigned int ambient_color;
@ -66,6 +67,7 @@ namespace collada::scene {
.uniform = {
// vertex
.transform = 0,
.world_transform = 1,
// fragment
.emission_color = 10,
.ambient_color = 11,
@ -481,30 +483,38 @@ namespace collada::scene {
}
}
void state::draw_node(types::node const & node, instance_types::node const & node_instance)
void state::draw_node(XMMATRIX const& ext_transform, types::node const & node, instance_types::node const & node_instance)
{
XMMATRIX transform = node_instance.world * view::state.transform;
if (node.instance_geometries_count) {
XMMATRIX world_transform = node_instance.world * ext_transform;
XMMATRIX transform = world_transform * view::state.transform;
XMFLOAT4X4 float_transform;
XMStoreFloat4x4(&float_transform, transform);
XMFLOAT4X4 float_world_transform;
XMStoreFloat4x4(&float_world_transform, world_transform);
if (node.instance_geometries_count) {
glUseProgram(collada::effect::program_static);
glUniformMatrix4fv(layout.uniform.transform, 1, false, (float *)&float_transform);
glUniformMatrix4fv(layout.uniform.world_transform, 1, false, (float *)&float_world_transform);
draw_instance_geometries(node.instance_geometries, node.instance_geometries_count);
}
if (node.instance_controllers_count) {
XMMATRIX transform = view::state.transform;
XMMATRIX world_transform = ext_transform;
XMMATRIX transform = world_transform * view::state.transform;
XMFLOAT4X4 float_transform;
XMStoreFloat4x4(&float_transform, transform);
XMFLOAT4X4 float_world_transform;
XMStoreFloat4x4(&float_world_transform, world_transform);
glUseProgram(collada::effect::program_skinned);
glUniformMatrix4fv(layout.uniform.transform, 1, false, (float *)&float_transform);
glUniformMatrix4fv(layout.uniform.world_transform, 1, false, (float *)&float_world_transform);
draw_instance_controllers(node.instance_controllers, node.instance_controllers_count);
}
}
void state::draw()
void state::draw(XMMATRIX const& ext_transform)
{
unsigned int effects[] = {collada::effect::program_static, collada::effect::program_skinned};
for (int i = 0; i < 2; i++) {
@ -528,7 +538,7 @@ namespace collada::scene {
if (((node_draw_type & 0b10) == 0) && (node.type == types::node_type::JOINT))
continue;
draw_node(node, node_state.node_instances[i]);
draw_node(ext_transform, node, node_state.node_instances[i]);
}
}

View File

@ -25,6 +25,7 @@
#include "boids_scene.h"
#include "collada/effect.h"
#include "collada/scene.h"
#include "collada/animate.h"
#include "collada/types.h"
#include "collada/instance_types.h"
#include "flame.h"
@ -188,16 +189,18 @@ void load()
scene_state.load_scene(&eidelwind::descriptor);
node_eye = scene_state.find_node_by_name("Camera001");
assert(node_eye != nullptr);
view::state.eye = XMVector3Transform(XMVectorZero(), node_eye->world);
view::state.eye = XMVectorSet(26.85, 10.71, 53.34, 0);
//view::state.eye = XMVector3Transform(XMVectorZero(), node_eye->world);
node_at = scene_state.find_node_by_name("Camera001.Target");
assert(node_at != nullptr);
view::state.at = XMVector3Transform(XMVectorZero(), node_at->world);
view::state.at = XMVectorSet(17.07, 10.61, 51.38, 0);
//view::state.at = XMVector3Transform(XMVectorZero(), node_at->world);
view::state.direction = XMVector3Normalize(view::state.at - view::state.eye);
view::state.normal = XMVector3Cross(view::state.direction, view::state.up);
view::state.forward = -XMVector3Cross(view::state.normal, view::state.up);
view::state.pitch = 0;
view::state.pitch = -0.19;
//////////////////////////////////////////////////////////////////////
// flame
@ -350,7 +353,7 @@ void update_joystick(float lx, float ly,
int leftshoulder, int rightshoulder,
int start)
{
float translate_rate = 2.0;
float translate_rate = 0.5;
float forward = -ly * translate_rate;
float strafe = lx * translate_rate;
@ -399,11 +402,15 @@ void update_joystick(float lx, float ly,
*/
}
static float ext_position = 0;
void update(float time)
{
current_time = time;
scene_state.update(time);
ext_position = collada::animate::loop(time, 10);
/*
view::state.eye = XMVector3Transform(XMVectorZero(), node_eye->world);
if (node_at == nullptr)
@ -477,7 +484,7 @@ void draw()
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glClearDepth(-1.0f);
if (false) {
if (true) {
// possibly re-initialize geometry buffer if window width/height changes
init_geometry_buffer(geometry_buffer_pnc, geometry_buffer_pnc_types);
@ -486,11 +493,21 @@ void draw()
minecraft::draw();
non_block::draw();
//non_block::draw();
flame::draw(minecraft::current_world->light_uniform_buffer,
minecraft::current_world->light_count);
float scale = 0.03f;
float pos = ext_position * 51.228f * scale * 2.0f;
XMMATRIX ext_transform
= XMMatrixScaling(scale, scale, scale)
* XMMatrixRotationZ(XM_PI * 0.5f)
* XMMatrixTranslation(8 + pos, 11, 50.5);
scene_state.draw(ext_transform);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
@ -506,7 +523,7 @@ void draw()
} else {
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
scene_state.draw();
//scene_state.draw();
hud::draw();
}