created particle system
This commit is contained in:
parent
d42db622e7
commit
bba99d4d91
|
|
@ -9,6 +9,15 @@ const lua = @import("lua");
|
|||
const pod = lua.pod;
|
||||
// LUA END
|
||||
|
||||
// vector versions.
|
||||
pub const f32x4 = @Vector(4, f32);
|
||||
pub const f32x8 = @Vector(8, f32);
|
||||
pub const f32x16 = @Vector(16, f32);
|
||||
|
||||
pub const f32x4_zero = std.mem.zeroes(@Vector(4, f32));
|
||||
pub const f32x8_zero = std.mem.zeroes(@Vector(8, f32));
|
||||
pub const f32x16_zero = std.mem.zeroes(@Vector(16, f32));
|
||||
|
||||
pub const Rayf = RayType(Vectorf);
|
||||
|
||||
pub fn matToScalef(mat: anytype) Vectorf {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,335 @@
|
|||
// particle system
|
||||
//
|
||||
// last one we need to implement is a ParticleComposite,
|
||||
// this is a component which owns a particle emitter component (adding one if it does not exist)
|
||||
//
|
||||
// and generates/modifies particles system properties over time.
|
||||
//
|
||||
// just thinking... with meta reflection. I wonder if it is possible to codegen
|
||||
// a generic "timeline" runner capable of modifying any arbitrary float, bool etc... over time.
|
||||
//
|
||||
// that could be
|
||||
|
||||
pub const EmitterState = enum {
|
||||
dead, // emitter is not creating any particles
|
||||
alive, // emitter is creating particles up to max_porticles
|
||||
paused, // emitter is not updating
|
||||
};
|
||||
|
||||
pub const ParticleRandRangef = struct {
|
||||
min: f32 = 0,
|
||||
max: f32 = 0,
|
||||
|
||||
pub var randomFunc: std.Random = undefined;
|
||||
pub var randomEngine: std.Random.DefaultPrng = undefined;
|
||||
|
||||
pub fn set(self: *@This(), v: f32) void {
|
||||
self.min = v;
|
||||
self.max = v;
|
||||
}
|
||||
|
||||
pub fn getRange(self: @This()) f32 {
|
||||
if (std.math.approxEqAbs(f32, self.min, self.max, 0.0001))
|
||||
return self.min;
|
||||
|
||||
const x = (randomFunc.float(f32) +
|
||||
randomFunc.float(f32) +
|
||||
randomFunc.float(f32) +
|
||||
randomFunc.float(f32)) / 4;
|
||||
|
||||
return x * (self.max - self.min) + self.min;
|
||||
}
|
||||
};
|
||||
|
||||
pub const EmitterShape = union(enum(u8)) {
|
||||
spherical: struct {
|
||||
radius: f32 = 50.0,
|
||||
innerRadius: f32 = 0,
|
||||
// distrobution: =
|
||||
},
|
||||
conal: struct {
|
||||
direction: core.Vectorf,
|
||||
angle: f32,
|
||||
innerRadius: f32 = 0,
|
||||
},
|
||||
};
|
||||
|
||||
pub const Life = struct {
|
||||
current: f32,
|
||||
max: f32,
|
||||
};
|
||||
|
||||
pub const ParticlePVA = struct {
|
||||
position: core.f32x4 = core.f32x4_zero,
|
||||
velocity: core.f32x4 = core.f32x4_zero,
|
||||
acceleration: core.f32x4 = core.f32x4_zero,
|
||||
};
|
||||
|
||||
pub const Rotationals = struct {
|
||||
quat: core.f32x4 = .{},
|
||||
spinVector: core.f32x4 = .{},
|
||||
angularMomentum: f32 = 0.0,
|
||||
};
|
||||
|
||||
pub const RenderInfo = struct {
|
||||
meshIndex: u32 = 0,
|
||||
textureIndex: u32 = 0,
|
||||
};
|
||||
|
||||
pub const ParticleEmitter = struct {
|
||||
pub var BaseContainer: *core.SparseSet(ParticleEmitter) = undefined;
|
||||
pub const ComponentName = "ParticleEmitter";
|
||||
pub const ScriptExports: []const []const u8 = &.{};
|
||||
|
||||
// per particle information
|
||||
life: std.ArrayListUnmanaged(Life) = .{},
|
||||
particlesPVA: std.ArrayListUnmanaged(ParticlePVA) = .{},
|
||||
finals: std.ArrayListUnmanaged(core.Mat) = .{},
|
||||
renderInfo: std.ArrayListUnmanaged(RenderInfo) = .{},
|
||||
|
||||
particleAcceleration: ParticleRandRangef = .{ .min = 0.0, .max = 0.0 },
|
||||
particleVelocity: ParticleRandRangef = .{ .min = 8, .max = 10 },
|
||||
particleLife: ParticleRandRangef = .{ .min = 2, .max = 2 },
|
||||
|
||||
spawnRate: ParticleRandRangef = .{ .min = 10, .max = 10 },
|
||||
nextSpawn: f64 = 0.0,
|
||||
|
||||
gravity: ?core.Vectorf = null,
|
||||
maxParticles: u32 = 100,
|
||||
|
||||
// globalScale: f32 = 1.0, not implemented
|
||||
|
||||
state: EmitterState = .dead,
|
||||
billboard: bool = true,
|
||||
|
||||
// if billboard is set, the billboard bit will be set
|
||||
// and only position and scale will be used to render the particle.
|
||||
|
||||
// an empty list means that this will use quad_mesh
|
||||
mesh: std.ArrayListUnmanaged(rend.IndexedMesh) = .{},
|
||||
|
||||
// empty list means will use t_white
|
||||
texture: std.ArrayListUnmanaged(*rend.Texture) = .{},
|
||||
|
||||
emitterLife: f64 = 0.0, // 0.0 means this emitter lives forever.
|
||||
emitterMaxLife: f64 = 0.0,
|
||||
emitterShape: EmitterShape = .{ .spherical = .{} },
|
||||
|
||||
_showDebug: bool = false,
|
||||
|
||||
entity: core.Entity = undefined,
|
||||
|
||||
pub fn updatePVA(self: *@This(), dt: f64) void {
|
||||
// should generate SIMD operations
|
||||
|
||||
const gravity = if (self.gravity) |gravity| gravity.toZm() else core.f32x4_zero;
|
||||
|
||||
for (self.particlesPVA.items) |*pva| {
|
||||
pva.velocity = pva.acceleration * @as(core.f32x4, @splat(@floatCast(dt))) + gravity * @as(core.f32x4, @splat(@floatCast(dt))) + pva.velocity;
|
||||
pva.position = pva.velocity * @as(core.f32x4, @splat(@floatCast(dt))) + pva.position;
|
||||
if (self._showDebug) {
|
||||
core.debugSphere(core.Vectorf.fromArray(pva.position), 0.1, .{ .color = .{ .y = 1.0, .x = positionLength(pva.velocity) / 10 } });
|
||||
// core.debugSphere(core.Vectorf.Zeroes, 0.1, .{});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inline fn positionLength(f: core.f32x4) f32 {
|
||||
return @sqrt((f[0] * f[0]) + (f[1] * f[1]) + (f[2] * f[2]) + (f[3] * f[3]));
|
||||
}
|
||||
|
||||
pub fn updateParticleLife(self: *@This(), dt: f64) void {
|
||||
// should generate SIMD operations
|
||||
const dt32: f32 = @floatCast(dt);
|
||||
|
||||
for (self.life.items) |*life| {
|
||||
if (life.max > 0)
|
||||
life.current -= dt32;
|
||||
}
|
||||
|
||||
var i: usize = 0;
|
||||
while (i < self.life.items.len) : (i += 1) {
|
||||
if (self.life.items[i].current < 0) {
|
||||
self.removeParticle(i);
|
||||
}
|
||||
}
|
||||
|
||||
switch (self.emitterShape) {
|
||||
.spherical => |spherical| {
|
||||
i = 0;
|
||||
while (i < self.particlesPVA.items.len) : (i += 1) {
|
||||
if (positionLength(self.particlesPVA.items[i].position) > spherical.radius) {
|
||||
self.removeParticle(i);
|
||||
}
|
||||
}
|
||||
},
|
||||
.conal => {
|
||||
@panic("not implemented");
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
pub fn removeParticle(self: *@This(), i: usize) void {
|
||||
_ = self.life.swapRemove(i);
|
||||
_ = self.particlesPVA.swapRemove(i);
|
||||
_ = self.finals.swapRemove(i);
|
||||
_ = self.renderInfo.swapRemove(i);
|
||||
}
|
||||
|
||||
pub fn updateSpawn(self: *@This(), dt: f64) void {
|
||||
self.nextSpawn -= dt;
|
||||
|
||||
if (self.nextSpawn > 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (self.nextSpawn < 0 and self.life.items.len >= self.maxParticles) {
|
||||
self.nextSpawn = 0.0;
|
||||
return;
|
||||
}
|
||||
|
||||
while (self.nextSpawn < 0) {
|
||||
self.spawnParticle() catch {
|
||||
core.engine_err(" UNABLE TO SPAWN PARTICLE", .{});
|
||||
};
|
||||
|
||||
// generate random values for the next spawn
|
||||
self.nextSpawn += 1.0 / @as(f64, @floatCast(self.spawnRate.getRange()));
|
||||
}
|
||||
}
|
||||
|
||||
pub fn start(self: *@This()) void {
|
||||
self.state = .alive;
|
||||
}
|
||||
|
||||
pub fn generatePVA(self: *@This()) ParticlePVA {
|
||||
switch (self.emitterShape) {
|
||||
.spherical => |spherical| {
|
||||
const radius = ParticleRandRangef{ .min = -spherical.innerRadius, .max = spherical.innerRadius };
|
||||
|
||||
const oneRand = ParticleRandRangef{ .min = -1.0, .max = 1.0 };
|
||||
const v = core.Vectorf{ .x = oneRand.getRange(), .y = oneRand.getRange(), .z = oneRand.getRange() };
|
||||
const v2 = v.normalize();
|
||||
|
||||
const pva: ParticlePVA = .{
|
||||
.velocity = v2.fmul(self.particleVelocity.getRange()).toZm(),
|
||||
.position = .{
|
||||
radius.getRange(),
|
||||
radius.getRange(),
|
||||
radius.getRange(),
|
||||
1.0,
|
||||
},
|
||||
.acceleration = v2.fmul(self.particleAcceleration.getRange()).toZm(),
|
||||
};
|
||||
return pva;
|
||||
},
|
||||
.conal => |conal| {
|
||||
_ = conal;
|
||||
@panic("not implemented");
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
fn spawnParticle(self: *@This()) !void {
|
||||
const pva = self.generatePVA();
|
||||
|
||||
const life = self.particleLife.getRange();
|
||||
try self.life.append(gParticleAllocator, .{ .current = life, .max = life });
|
||||
|
||||
try self.particlesPVA.append(gParticleAllocator, pva);
|
||||
|
||||
// renderinfo not used rn
|
||||
try self.renderInfo.append(gParticleAllocator, .{});
|
||||
try self.finals.append(gParticleAllocator, std.mem.zeroes(core.Mat));
|
||||
}
|
||||
|
||||
fn updateLife(self: *@This(), dt: f64) void {
|
||||
if (self.emitterMaxLife <= 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
self.emitterLife -= dt;
|
||||
if (self.emitterLife <= 0) {
|
||||
self.state = .dead;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn update(self: *@This(), dt: f64) void {
|
||||
if (self.state != .dead) {
|
||||
self.updateSpawn(dt);
|
||||
}
|
||||
|
||||
// core.debugSphere(self.entity.fetch(core.Scene).?.getPosition(), self.emitterShape.spherical.radius, .{});
|
||||
|
||||
self.updatePVA(dt);
|
||||
self.updateParticleLife(dt);
|
||||
self.updateLife(dt);
|
||||
}
|
||||
|
||||
pub fn initECS(self: *@This(), handle: core.SetHandle) void {
|
||||
// get the mesh component
|
||||
self.entity = core.Entity{ .handle = handle };
|
||||
|
||||
if (self.entity.fetch(core.Scene)) |scene| {
|
||||
_ = scene;
|
||||
} else {
|
||||
_ = self.entity.addComponent(core.Scene);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn deinit(self: *@This()) void {
|
||||
_ = self;
|
||||
}
|
||||
};
|
||||
|
||||
var gParticleAllocator: std.mem.Allocator = undefined;
|
||||
|
||||
pub const Effect = struct {};
|
||||
|
||||
pub const ParticleSystem = struct {
|
||||
particleArena: std.heap.ArenaAllocator,
|
||||
allocator: std.mem.Allocator,
|
||||
|
||||
pub var NeonObjectTable: core.EngineObjectVTable = core.EngineObjectVTable.from(@This(), "rend.ParticleSystem");
|
||||
|
||||
pub fn create(allocator: std.mem.Allocator) !*@This() {
|
||||
const self = try allocator.create(@This());
|
||||
|
||||
self.* = .{
|
||||
.particleArena = std.heap.ArenaAllocator.init(allocator),
|
||||
.allocator = allocator,
|
||||
};
|
||||
|
||||
gParticleAllocator = self.particleArena.allocator();
|
||||
|
||||
ParticleRandRangef.randomEngine = std.Random.DefaultPrng.init(0x1234);
|
||||
ParticleRandRangef.randomFunc = ParticleRandRangef.randomEngine.random();
|
||||
|
||||
try core.defineComponent(ParticleEmitter, allocator);
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
pub fn tick(self: *@This(), dt: f64) void {
|
||||
var z = tracy.ZoneN(@src(), "Particle System");
|
||||
defer z.End();
|
||||
|
||||
_ = self;
|
||||
|
||||
for (ParticleEmitter.BaseContainer.dense.items) |*emitter| {
|
||||
emitter.value.update(dt);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn destroy(self: *@This()) void {
|
||||
core.undefineComponent(ParticleEmitter);
|
||||
|
||||
self.particleArena.deinit();
|
||||
self.allocator.destroy(self);
|
||||
}
|
||||
};
|
||||
|
||||
const core = @import("core");
|
||||
const rend = @import("../rend.zig");
|
||||
const std = @import("std");
|
||||
const tracy = core.tracy;
|
||||
|
|
@ -44,6 +44,11 @@ pub const Animator = animationSystem.Animator;
|
|||
|
||||
pub const setSkyboxTexture = renderer.setSkyboxTexture;
|
||||
|
||||
pub const particles = @import("particles/particles.zig");
|
||||
|
||||
pub const ParticleSystem = particles.ParticleSystem;
|
||||
pub const ParticleEmitter = particles.ParticleEmitter;
|
||||
|
||||
var rendAllocator: std.mem.Allocator = undefined;
|
||||
pub fn getAllocator() std.mem.Allocator {
|
||||
return rendAllocator;
|
||||
|
|
@ -66,6 +71,7 @@ pub fn start_module(spec: *core.SpecVariantMap, args: anytype, allocator: std.me
|
|||
try renderer.start();
|
||||
|
||||
_ = try context().createRendererEngineObject(animationSystem.AnimationSystem);
|
||||
_ = try context().createRendererEngineObject(particles.ParticleSystem);
|
||||
|
||||
try animationLoaders.initLoaders();
|
||||
try core.defineComponentList(ComponentList, allocator);
|
||||
|
|
|
|||
|
|
@ -1092,6 +1092,7 @@ pub fn registerRendererObject(comptime T: type, object: *anyopaque) !void {
|
|||
|
||||
pub fn setSkyboxTexture(name: []const u8) void {
|
||||
context().skyboxSystem.skyboxTextureName = core.MakeName(name);
|
||||
context().skyboxSystem.skyboxTexture = null;
|
||||
}
|
||||
|
||||
pub const getMesh = mesh_pool.getMesh;
|
||||
|
|
|
|||
|
|
@ -4,6 +4,8 @@ allocator: std.mem.Allocator,
|
|||
directionalLightSettings: bool = false,
|
||||
ssaoSettings: bool = false,
|
||||
|
||||
skyboxes: std.ArrayListUnmanaged(core.Name) = .{},
|
||||
|
||||
pub var NeonObjectTable: core.EngineObjectVTable = core.EngineObjectVTable.from(@This(), "extras.RendererDebug");
|
||||
|
||||
pub fn create(allocator: std.mem.Allocator) !*@This() {
|
||||
|
|
@ -52,11 +54,24 @@ pub fn windowOpen(entry: *igu.MenuEntry, dt: f64) void {
|
|||
_ = ig.sliderFloat("bias", &ssao.bias, 0.0025, 1.0, null, .{});
|
||||
_ = ig.checkbox("enable SSAO", &ssao.enable);
|
||||
}
|
||||
|
||||
var buffer: [256]u8 = undefined;
|
||||
|
||||
ig.textFmt("skyboxes", .{}) catch unreachable;
|
||||
ig.separator();
|
||||
|
||||
for (self.skyboxes.items) |*name| {
|
||||
const x = std.fmt.bufPrintZ(&buffer, "{s}##button", .{name.utf8()}) catch unreachable;
|
||||
if (ig.smallButton(x)) {
|
||||
rend.setSkyboxTexture(name.utf8());
|
||||
}
|
||||
}
|
||||
}
|
||||
ig.end();
|
||||
}
|
||||
|
||||
pub fn destroy(self: *@This()) void {
|
||||
self.skyboxes.deinit(self.allocator);
|
||||
self.allocator.destroy(self);
|
||||
}
|
||||
|
||||
|
|
|
|||
Binary file not shown.
|
After Width: | Height: | Size: 868 B |
|
|
@ -54,6 +54,8 @@ pub const ExternGameObject = struct {
|
|||
a: bool = false,
|
||||
// lib: bool = false,
|
||||
//s: u32 = 0x42,
|
||||
editParticle: ?core.Entity = null,
|
||||
savedGravity: core.Vectorf = .{},
|
||||
|
||||
pub fn loadMap2(self: *@This()) !void {
|
||||
if (self.tbMap) |tbMap| {
|
||||
|
|
@ -69,6 +71,81 @@ pub const ExternGameObject = struct {
|
|||
core.engine_log("map loaded", .{});
|
||||
}
|
||||
|
||||
const ItemWidth = 80;
|
||||
|
||||
pub fn displayRandRangeImgui(comptime Name: []const u8, range: *rend.particles.ParticleRandRangef) void {
|
||||
ig.textFmt(Name, .{}) catch {};
|
||||
ig.sameLine(0, 10);
|
||||
ig.setNextItemWidth(ItemWidth);
|
||||
_ = ig.inputFloat("Min##particleEd" ++ Name, &range.min, 1.0, 5.0, null, .{});
|
||||
ig.sameLine(0, 10);
|
||||
ig.setNextItemWidth(ItemWidth);
|
||||
_ = ig.inputFloat("Max##particleEd" ++ Name, &range.max, 1.0, 5.0, null, .{});
|
||||
}
|
||||
|
||||
pub fn editVector(comptime Name: []const u8, range: *core.Vectorf) void {
|
||||
ig.textFmt(Name, .{}) catch {};
|
||||
ig.sameLine(0, 10);
|
||||
ig.setNextItemWidth(ItemWidth);
|
||||
_ = ig.inputFloat("X##particleEd" ++ Name, &range.x, 1.0, 5.0, null, .{});
|
||||
ig.sameLine(0, 10);
|
||||
ig.setNextItemWidth(ItemWidth);
|
||||
_ = ig.inputFloat("Y##particleEd" ++ Name, &range.y, 1.0, 5.0, null, .{});
|
||||
ig.sameLine(0, 10);
|
||||
ig.setNextItemWidth(ItemWidth);
|
||||
_ = ig.inputFloat("Z##particleEd" ++ Name, &range.z, 1.0, 5.0, null, .{});
|
||||
}
|
||||
|
||||
pub fn particleDebug(self: *@This()) void {
|
||||
if (ig.begin("particleDebugger", null, .{})) {
|
||||
var buffer: [256]u8 = undefined;
|
||||
for (rend.ParticleEmitter.BaseContainer.dense.items, 0..) |*emitter, i| {
|
||||
ig.textFmt("emitter {d}", .{emitter.sparseIndex.index}) catch {};
|
||||
if (ig.smallButton(std.fmt.bufPrintZ(&buffer, "edit##{d}", .{i}) catch unreachable)) {
|
||||
self.editParticle = emitter.value.entity;
|
||||
}
|
||||
}
|
||||
}
|
||||
ig.end();
|
||||
|
||||
var checkbox: bool = true;
|
||||
|
||||
if (self.editParticle) |edit| {
|
||||
if (edit.fetch(rend.ParticleEmitter)) |emitter| {
|
||||
if (ig.begin("editParticle", null, .{})) {
|
||||
displayRandRangeImgui("Acceleration", &emitter.particleAcceleration);
|
||||
displayRandRangeImgui("Velocity", &emitter.particleVelocity);
|
||||
displayRandRangeImgui("Life", &emitter.particleLife);
|
||||
displayRandRangeImgui("spawnRate", &emitter.spawnRate);
|
||||
|
||||
if (emitter.gravity != null) {
|
||||
checkbox = true;
|
||||
} else {
|
||||
checkbox = false;
|
||||
}
|
||||
|
||||
if (ig.checkbox("hasGravity", &checkbox)) {
|
||||
if (!checkbox) {
|
||||
self.savedGravity = emitter.gravity.?;
|
||||
emitter.gravity = null;
|
||||
}
|
||||
|
||||
if (checkbox) {
|
||||
emitter.gravity = self.savedGravity;
|
||||
}
|
||||
}
|
||||
|
||||
if (emitter.gravity != null) {
|
||||
editVector("gravity", &emitter.gravity.?);
|
||||
}
|
||||
|
||||
_ = ig.inputInt("maaxParticles##particleEd", @ptrCast(&emitter.maxParticles), 1, 5, .{});
|
||||
}
|
||||
ig.end();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn create(allocator: std.mem.Allocator) !*@This() {
|
||||
const self = try Slack.create(allocator);
|
||||
self.* = .{
|
||||
|
|
@ -220,6 +297,7 @@ pub const ExternGameObject = struct {
|
|||
}
|
||||
}
|
||||
}
|
||||
self.particleDebug();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -76,6 +76,27 @@ const assetReferences = [_]assets.AssetImportReference{
|
|||
"m_crate",
|
||||
.{ .path = "meshes/Crate.obj" },
|
||||
),
|
||||
assets.MakeImportRefOptions(
|
||||
"Texture",
|
||||
"t_dark_skybox",
|
||||
.{
|
||||
.textureCube = true,
|
||||
.textureList = &.{
|
||||
"textures/DarkGrey.png", // cubemapfacePositivex, right
|
||||
"textures/DarkGrey.png", // cubemapfacePositivex, right
|
||||
"textures/DarkGrey.png", // cubemapfacePositivex, right
|
||||
"textures/DarkGrey.png", // cubemapfacePositivex, right
|
||||
"textures/DarkGrey.png", // cubemapfacePositivex, right
|
||||
"textures/DarkGrey.png", // cubemapfacePositivex, right
|
||||
//"sky_air/cube_right.png", // cubemapfacePositivex, right
|
||||
//"sky_air/cube_left.png", // cubemapfacePositivex, right
|
||||
//"sky_air/cube_up.png", // cubemapfacePositivex, right
|
||||
//"sky_air/cube_down.png", // cubemapfacePositivex, right
|
||||
//"sky_air/cube_back.png", // cubemapfacePositivex, right
|
||||
//"sky_air/cube_front.png", // cubemapfacePositivex, right
|
||||
},
|
||||
},
|
||||
),
|
||||
assets.MakeImportRefOptions(
|
||||
"Texture",
|
||||
"t_skybox",
|
||||
|
|
@ -93,6 +114,34 @@ const assetReferences = [_]assets.AssetImportReference{
|
|||
),
|
||||
};
|
||||
|
||||
pub const ParticleObject = struct {
|
||||
data: core.GameObjectData = undefined,
|
||||
entity: core.Entity,
|
||||
|
||||
pub fn create(alloc: std.mem.Allocator) !*@This() {
|
||||
const self = try alloc.create(@This());
|
||||
const e = try core.createEntity();
|
||||
|
||||
const particle = e.addComponent(rend.ParticleEmitter).?;
|
||||
particle._showDebug = true;
|
||||
particle.start();
|
||||
particle.gravity = .{ .y = -9.8 };
|
||||
|
||||
self.entity = e;
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
pub fn getEntity(self: *@This()) core.Entity {
|
||||
return self.entity;
|
||||
}
|
||||
|
||||
pub fn destroy(self: *@This()) void {
|
||||
self.entity.destroy();
|
||||
self.data.release(self);
|
||||
}
|
||||
};
|
||||
|
||||
pub const FoxObject = struct {
|
||||
data: core.GameObjectData = undefined,
|
||||
entity: core.Entity,
|
||||
|
|
@ -106,6 +155,7 @@ pub const FoxObject = struct {
|
|||
const mesh = fox.addComponent(rend.MeshComponent).?;
|
||||
mesh.setMesh("m_fox");
|
||||
mesh.setTexture("t_fox");
|
||||
|
||||
const animator = fox.addComponent(rend.Animator).?;
|
||||
animator.setSkeleton("sk_fox");
|
||||
animator.setAnimation("a_fox_survey");
|
||||
|
|
@ -187,11 +237,14 @@ pub fn prepare(self: *@This()) !void {
|
|||
// try self.tryLoadExtern("externGame");
|
||||
|
||||
// self.rendererDebugger = try extras.RendererDebug.create(self.allocator); //try core.createObject(extras.RendererDebug, .{});
|
||||
_ = try core.createObject(extras.RendererDebug, .{});
|
||||
const rendererDebug = try core.createObject(extras.RendererDebug, .{});
|
||||
try rendererDebug.skyboxes.append(rendererDebug.allocator, core.MakeName("t_skybox"));
|
||||
try rendererDebug.skyboxes.append(rendererDebug.allocator, core.MakeName("t_dark_skybox"));
|
||||
|
||||
//self.objectSpawner = try extras.ObjectSpawner.create(self.allocator);
|
||||
self.objectSpawner = try core.createObject(extras.ObjectSpawner, .{});
|
||||
try self.objectSpawner.addSpawnFunction("fox", FoxObject);
|
||||
try self.objectSpawner.addSpawnFunction("particle", ParticleObject);
|
||||
try self.objectSpawner.addSpawnFunction("doomplayer", DoomPlayer.DoomCanvas);
|
||||
try self.objectSpawner.addSpawnFunction("empire", @import("empire.zig"));
|
||||
try self.objectSpawner.addSpawnFunction("DamagedHelmet", DamagedHelmet);
|
||||
|
|
|
|||
Loading…
Reference in New Issue