rusting_engine 0.1.46

A high-performance Vulkano-based 3D engine with GPU physics.
#version 450
layout(local_size_x = 256, local_size_y = 1, local_size_z = 1) in;

struct InstanceData {
	mat4 model;
	vec4 color;
	vec4 mat_props;
	vec4 velocity;
	vec4 angular_velocity;
	vec4 physic_props;
};

layout(set = 0, binding = 0) buffer ReadBuf {
	InstanceData data[];
} read_buf;

layout(set = 0, binding = 1) buffer WriteBuf {
	InstanceData data[];
} write_buf;

layout(push_constant) uniform PushConstants {
	float dt;
	uint total_objects;
	uint offset;
	uint count;
	uint num_big_objects;
	uint _pad[3];
	vec4 global_gravity;
} pc;

mat3 skew(vec3 v) {
	return mat3(0.0, -v.z, v.y, v.z, 0.0, -v.x, -v.y, v.x, 0.0);
}

void main() {
	uint i = gl_GlobalInvocationID.x + pc.offset;
	if (i >= pc.offset + pc.count) return;
	
	write_buf.data[i] = read_buf.data[i];
	
	InstanceData me = read_buf.data[i];
	vec3 pos = me.model[3].xyz;
	vec3 vel = me.velocity.xyz;
	vec3 ang_vel = me.angular_velocity.xyz;
	float type = me.physic_props.x;
	float mass = me.physic_props.y;
	float gravity_scale = me.physic_props.z;

	if (mass <= 0.0) return;

	vel += pc.global_gravity.xyz * gravity_scale * pc.dt;
	pos += vel * pc.dt;

	vec3 scale = vec3(length(me.model[0].xyz), length(me.model[1].xyz), length(me.model[2].xyz));
	vec3 half_extents = scale * 0.5;
	mat3 rot = mat3(me.model[0].xyz / scale.x, me.model[1].xyz / scale.y, me.model[2].xyz / scale.z);
	if (length(ang_vel) > 0.001) {
		rot += skew(ang_vel) * rot * pc.dt;
		vec3 c0 = normalize(rot[0]);
		vec3 c1 = normalize(rot[1] - dot(c0, rot[1]) * c0);
		vec3 c2 = cross(c0, c1);
		rot = mat3(c0, c1, c2);
	}

	float lowest_y = (type > 0.5)
		? scale.x
		: (half_extents.x * abs(rot[0].y) + half_extents.y * abs(rot[1].y) + half_extents.z * abs(rot[2].y));
	if (pos.y < lowest_y) {
		pos.y = lowest_y;
		if (vel.y < 0.0) {
			vel.y *= -me.velocity.w;
			float damping = clamp(1.0 - me.angular_velocity.w, 0.0, 1.0);
			vel.xz *= damping;
			ang_vel *= damping;
		}
	}

	me.model[0] = vec4(rot[0] * scale.x, 0.0);
	me.model[1] = vec4(rot[1] * scale.y, 0.0);
	me.model[2] = vec4(rot[2] * scale.z, 0.0);
	me.model[3].xyz = pos;

	me.velocity.xyz = vel;
	me.angular_velocity.xyz = ang_vel;

	write_buf.data[i] = me;
}