317 lines
9.9 KiB
Zig
317 lines
9.9 KiB
Zig
const std = @import("std");
|
|
const vk = @import("vulkan");
|
|
const resources = @import("resources");
|
|
const core = @import("core");
|
|
const VkConstants = @import("vk_constants.zig");
|
|
const graphics = @import("graphics.zig");
|
|
const meshes = @import("mesh.zig");
|
|
const NeonVkContext = @import("vk_renderer.zig").NeonVkContext;
|
|
const materials = @import("materials.zig");
|
|
const animationSystem = @import("animation/animationSystem.zig");
|
|
const Animator = animationSystem.Animator;
|
|
|
|
const Material = materials.Material;
|
|
const EulerAngles = core.EulerAngles;
|
|
const Mat = core.Mat;
|
|
const Vectorf = core.Vectorf;
|
|
const Quat = core.Quat;
|
|
const zm = core.zm;
|
|
const mul = zm.mul;
|
|
|
|
const Mesh = meshes.Mesh;
|
|
const mesh_pool = @import("vk_renderer/vk_mesh_pool.zig");
|
|
const IndexedMesh = mesh_pool.IndexedMesh;
|
|
|
|
// lol we need to rename this thing again, it should be called RenderMesh
|
|
pub const StaticMeshSet = core.SparseSet(StaticMesh);
|
|
|
|
pub const StaticMesh = struct {
|
|
const Self = @This();
|
|
|
|
mesh: ?IndexedMesh = null,
|
|
// texture: ?vk.DescriptorSet = null,
|
|
textureId: ?u32 = null,
|
|
transform: core.Mat = core.zm.translation(0, 0, 0),
|
|
visibility: bool = true,
|
|
|
|
// new position and rotator based api
|
|
position: Vectorf = .{},
|
|
rotation: Quat = .{ 0, 0, 0, 1 },
|
|
scale: Vectorf = .{ .x = 1, .y = 1, .z = 1 },
|
|
|
|
textureName: core.Name = core.NameInvalid,
|
|
meshName: core.Name = core.NameInvalid,
|
|
|
|
animated: bool = false, // todo remove
|
|
animator: ?*Animator = null,
|
|
|
|
flags: Flags0 = .{},
|
|
|
|
pub var BaseContainer: *StaticMeshSet = undefined;
|
|
pub const ComponentName = "StaticMesh";
|
|
|
|
pub const ScriptExports: []const []const u8 = &.{
|
|
"applyRelativeRotationX",
|
|
"applyRelativeRotationY",
|
|
"applyRelativeRotationZ",
|
|
"setMesh",
|
|
"setTextureByName",
|
|
};
|
|
|
|
pub const Flags0 = packed struct(u32) {
|
|
alwaysInFront: bool = false,
|
|
useAltFov: bool = false,
|
|
_pad: u30 = 0,
|
|
};
|
|
|
|
pub fn setMeshByName(self: *@This(), meshName: core.Name) void {
|
|
self.meshName = meshName;
|
|
}
|
|
|
|
// script function
|
|
pub fn setMesh(self: *@This(), meshName: []const u8) void {
|
|
const name = core.MakeName(meshName);
|
|
self.mesh = graphics.getIndexedMeshByName(core.MakeName(meshName));
|
|
self.meshName = name;
|
|
}
|
|
|
|
pub fn fromTransform(transform: core.Mat) Self {
|
|
var self = Self{
|
|
.mesh = null,
|
|
.transform = transform,
|
|
.position = undefined,
|
|
.rotation = undefined,
|
|
.scale = undefined,
|
|
};
|
|
|
|
self.updateScalars();
|
|
|
|
return self;
|
|
}
|
|
|
|
pub fn setTexture(self: *Self, textureName: []const u8) void {
|
|
var name = core.MakeName(textureName);
|
|
self.textureId = graphics.getContext().textureIds.get(name.handle());
|
|
self.textureName = name;
|
|
}
|
|
|
|
pub fn setTextureByName(self: *Self, _name: core.Name) void {
|
|
var name = _name;
|
|
self.textureId = graphics.getContext().textureIds.get(name.handle());
|
|
self.textureName = name;
|
|
}
|
|
|
|
pub fn updateTexture(self: *@This(), gc: *NeonVkContext) void {
|
|
self.textureId = gc.textureIds.get(self.textureName.handle());
|
|
}
|
|
|
|
pub fn applyTransform(self: *StaticMesh, transform: core.Mat) void {
|
|
self.transform = core.zm.mul(self.transform, transform);
|
|
self.updateScalars();
|
|
}
|
|
|
|
pub fn applyRelativeRotationX(self: *StaticMesh, angle: f32) void {
|
|
var imat = core.zm.identity();
|
|
imat[0][3] = -self.transform[0][3];
|
|
imat[1][3] = -self.transform[1][3];
|
|
imat[2][3] = -self.transform[2][3];
|
|
|
|
const rmat = core.zm.identity();
|
|
imat[0][3] = self.transform[0][3];
|
|
imat[1][3] = self.transform[1][3];
|
|
imat[2][3] = self.transform[2][3];
|
|
|
|
var newTransform = core.zm.mul(imat, self.transform);
|
|
newTransform = core.zm.mul(core.zm.rotationX(angle), newTransform);
|
|
newTransform = core.zm.mul(rmat, newTransform);
|
|
self.transform = newTransform;
|
|
}
|
|
|
|
pub fn applyRelativeRotationZ(self: *StaticMesh, angle: f32) void {
|
|
var imat = core.zm.identity();
|
|
imat[0][3] = -self.transform[0][3];
|
|
imat[1][3] = -self.transform[1][3];
|
|
imat[2][3] = -self.transform[2][3];
|
|
|
|
const rmat = core.zm.identity();
|
|
imat[0][3] = self.transform[0][3];
|
|
imat[1][3] = self.transform[1][3];
|
|
imat[2][3] = self.transform[2][3];
|
|
|
|
var newTransform = core.zm.mul(imat, self.transform);
|
|
newTransform = core.zm.mul(core.zm.rotationZ(angle), newTransform);
|
|
newTransform = core.zm.mul(rmat, newTransform);
|
|
self.transform = newTransform;
|
|
}
|
|
|
|
pub fn applyRelativeRotationY(self: *StaticMesh, angle: f32) void {
|
|
var imat = core.zm.identity();
|
|
imat[0][3] = -self.transform[0][3];
|
|
imat[1][3] = -self.transform[1][3];
|
|
imat[2][3] = -self.transform[2][3];
|
|
|
|
const rmat = core.zm.identity();
|
|
imat[0][3] = self.transform[0][3];
|
|
imat[1][3] = self.transform[1][3];
|
|
imat[2][3] = self.transform[2][3];
|
|
|
|
var newTransform = core.zm.mul(imat, self.transform);
|
|
newTransform = core.zm.mul(core.zm.rotationY(angle), newTransform);
|
|
newTransform = core.zm.mul(rmat, newTransform);
|
|
self.transform = newTransform;
|
|
}
|
|
|
|
pub fn updateScalars(self: *StaticMesh) void {
|
|
self.position = Vectorf.fromZm(mul(self.transform, Vectorf.new(0.0, 0.0, 0.0).toZm()));
|
|
self.rotation = zm.matToQuat(self.transform);
|
|
self.scale = core.matToScalef(self.transform);
|
|
}
|
|
|
|
pub fn applyScalars(self: *StaticMesh) void {
|
|
var newTransform = core.zm.mul(
|
|
core.zm.scalingV(self.scale.toZm()),
|
|
core.zm.matFromQuat(self.rotation),
|
|
);
|
|
newTransform = core.zm.mul(
|
|
newTransform,
|
|
core.zm.translationV(self.position.toZm()),
|
|
);
|
|
self.transform = newTransform;
|
|
}
|
|
|
|
pub fn initECS(self: *@This(), handle: core.ObjectHandle) void {
|
|
const entity = core.Entity.fromHandle(handle);
|
|
if (entity.get(core.Scene)) |scene| {
|
|
self.position = scene.getPosition();
|
|
self.rotation = scene.getRotation().quat;
|
|
self.scale = scene.getScaleV();
|
|
} else {
|
|
_ = entity.addComponent(core.Scene);
|
|
}
|
|
}
|
|
};
|
|
|
|
fn makePerspective(fov: f32, aspect: f32, near: f32, far: f32) Mat {
|
|
const proj = core.zm.perspectiveFovRh(
|
|
core.radians(fov),
|
|
aspect,
|
|
near,
|
|
far,
|
|
);
|
|
// proj[1][1] *= -1;
|
|
return proj;
|
|
}
|
|
|
|
// Camera coordinate system:
|
|
//
|
|
// from you as a user, staring at the screen:
|
|
//
|
|
// This is a right handed coordinate system
|
|
//
|
|
// forward = +Z (index finger)
|
|
// left = +X (middle finger)
|
|
// up = +Y (thumb)
|
|
|
|
const ecs = core.ecs;
|
|
|
|
pub const Camera = struct {
|
|
fov: f32 = 70.0,
|
|
altFov: f32 = 70.0,
|
|
aspect: f32 = 16.0 / 9.0,
|
|
near_clipping: f32 = 0.1,
|
|
far_clipping: f32 = 10000.0,
|
|
|
|
position: Vectorf = Vectorf{ .x = 0.0, .y = 0.0, .z = 0.0 },
|
|
rotation: Quat, // todo, remove, we only work with euler tracks now for camera.
|
|
|
|
// applied in that order,
|
|
yaw: f32 = 0,
|
|
pitch: f32 = 0,
|
|
roll: f32 = 0,
|
|
|
|
transform: core.Transform = zm.identity(),
|
|
worldTransform: Mat = zm.identity(),
|
|
projection: Mat = makePerspective(
|
|
core.radians(70.0), // angle
|
|
16.0 / 9.0,
|
|
0.1,
|
|
200000,
|
|
),
|
|
projectionAlt: Mat = makePerspective(
|
|
core.radians(70.0), // angle
|
|
16.0 / 9.0,
|
|
0.0001,
|
|
1000,
|
|
),
|
|
|
|
final: Mat = zm.identity(),
|
|
finalAlt: Mat = zm.identity(),
|
|
|
|
pub const EcsComponentDefinition = ecs.DefineComponent(@This(), .set); // set, map, multiset, maplist
|
|
|
|
pub fn init() Camera {
|
|
return .{
|
|
.rotation = zm.quatFromRollPitchYaw(0.0, 0.0, 0.0),
|
|
};
|
|
}
|
|
|
|
pub fn translate(self: *Camera, offset: core.Vectorf) void {
|
|
var off: core.Vectorf = offset;
|
|
off.y = offset.y;
|
|
off.x = offset.x;
|
|
off.z = offset.z;
|
|
self.*.position = self.position.add(off);
|
|
}
|
|
|
|
pub fn getRotation(self: *Camera) Quat {
|
|
return zm.quatFromMat(self.transform);
|
|
}
|
|
|
|
pub fn setRotationEuler(self: *@This(), x: f32, y: f32, z: f32) void {
|
|
self.rotation = core.zm.quatFromRollPitchYaw(x, y + core.radians(180.0), z);
|
|
}
|
|
|
|
pub fn updateCamera(self: *Camera) void {
|
|
self.projection = zm.perspectiveFovRh(core.radians(self.fov), 16.0 / 9.0, 0.1, 200000);
|
|
self.projection[1][1] *= -1;
|
|
|
|
self.projectionAlt = zm.perspectiveFovRh(core.radians(self.altFov), 16.0 / 9.0, 0.01, 200000);
|
|
self.projectionAlt[1][1] *= -1;
|
|
|
|
// self.projectionAlt = self.projection;
|
|
}
|
|
|
|
pub fn resolve(self: *Camera) void {
|
|
{
|
|
var base = core.zm.identity();
|
|
base = mul(core.zm.rotationY(-self.yaw), base);
|
|
base = mul(core.zm.rotationX(self.pitch), base);
|
|
base = mul(core.zm.rotationZ(self.roll), base);
|
|
|
|
const pr2 = core.scene.SceneObjectPosRot{
|
|
.position = self.position,
|
|
};
|
|
|
|
self.worldTransform = mul(base, pr2.toTransform());
|
|
}
|
|
|
|
// calculate viewProjections
|
|
{
|
|
var base = core.zm.rotationY(self.yaw + core.radians(180.0));
|
|
base = mul(base, core.zm.rotationX(self.pitch));
|
|
base = mul(base, core.zm.rotationZ(self.roll));
|
|
self.transform = base;
|
|
// self.transform = mul(
|
|
// base,
|
|
// mul(zm.matFromQuat(self.rotation), zm.rotationY(core.radians(180.0))),
|
|
// );
|
|
var position = self.position;
|
|
// position.x *= -1;
|
|
// position.z *= -1;
|
|
self.transform = mul(zm.translationV(position.fmul(-1).toZm()), self.transform);
|
|
self.final = mul(self.transform, self.projection);
|
|
self.finalAlt = mul(self.transform, self.projectionAlt);
|
|
}
|
|
}
|
|
};
|