A particle is a function of its age, not a thing that is stepped (#73)
game-maker / suite (push) Failing after 4m22s
game-maker / suite (push) Failing after 4m22s
The asset type `particles` is placeable and carries a graph at the same time — `behavior` was the blueprint. Because a continuous emitter gives birth to particle n at time n/rate, the whole field is a function of the clock rather than of the frames: no ring-buffer bookkeeping, exact time jumps, reproducibility as a measurable property. compile.ts follows compileShader's frame but emits JS closures into a Float64Array instead of GLSL, and without eval; a node with two consumers is evaluated once. Drawing is one Pixi ParticleContainer per source, so one draw call. Collision, wind and braking in flight are out for good — that is the price of the formula model, not an omission. The tab count goes from nine to ten, which is exactly the case #84 was built for one day earlier: at 1280 px the row no longer holds every tab, so guard 14b now asks for hidden.length > 0 instead of === 0.
This commit is contained in:
1 parent
f83c568999
commit
0f9e1611d1
39 files changed
+2386
-32
No files matched your search
@@ -12,6 +12,7 @@ import {
|
||||
nodeDef,
|
||||
STATE,
|
||||
} from '../graph';
|
||||
import { isParticleNodeDef } from '../particles/nodes';
|
||||
import { isShaderNodeDef } from '../shader/nodes';
|
||||
import type { Asset, TextureFrame } from '../model/Asset';
|
||||
import { isAssetType } from '../model/AssetTypes';
|
||||
@@ -48,6 +49,7 @@ import {
|
||||
type StructFieldDef,
|
||||
variableDef,
|
||||
} from '../properties/PropertySchema';
|
||||
import { particleParamDefs } from '../properties/particles';
|
||||
import { SHADER_KEY, shaderParamDefs } from '../properties/shaders';
|
||||
|
||||
/**
|
||||
@@ -64,6 +66,7 @@ export function deserializeProject(raw: unknown, fallbackId = ''): Project {
|
||||
const rawProps = new Map<string, Record<string, unknown>>();
|
||||
const shaderGraphs = new Map<string, Graph>();
|
||||
const shaderRows = new Map<string, PropertyDef[]>();
|
||||
const particleGraphs = new Map<string, Graph>();
|
||||
for (const a of rawAssets) {
|
||||
if (typeof a.id !== 'string' || !a.id || !isAssetType(a.type)) continue;
|
||||
rawProps.set(a.id, asRecord(a.props));
|
||||
@@ -71,6 +74,12 @@ export function deserializeProject(raw: unknown, fallbackId = ''): Project {
|
||||
const vars = normalizeVariables(a.variables);
|
||||
variables.set(a.id, vars);
|
||||
schemas.set(a.id, [...COMMON_PROPS, ...vars]);
|
||||
} else if (a.type === 'particles') {
|
||||
// A source's rows end with its own graph's parameters, so the graph is needed before the
|
||||
// overrides of the objects placed from it can be coerced.
|
||||
const graph = normalizeGraph(a.graph, isParticleNodeDef);
|
||||
particleGraphs.set(a.id, graph);
|
||||
schemas.set(a.id, [...schemaFor('particles'), ...particleParamDefs(graph)]);
|
||||
} else {
|
||||
if (a.type === 'shader') {
|
||||
const graph = normalizeGraph(a.graph, isShaderNodeDef);
|
||||
@@ -115,6 +124,8 @@ export function deserializeProject(raw: unknown, fallbackId = ''): Project {
|
||||
assets.push({ id, type, name, props, graph: normalizeGraph(a.graph, (def) => def.type === STATE) });
|
||||
} else if (type === 'shader') {
|
||||
assets.push({ id, type, name, props, graph: shaderGraphs.get(id) ?? createEmptyGraph() });
|
||||
} else if (type === 'particles') {
|
||||
assets.push({ id, type, name, props, graph: particleGraphs.get(id) ?? createEmptyGraph() });
|
||||
} else if (type === 'texture') {
|
||||
assets.push({ id, type, name, props, ...normalizeTexture(a, takenIds) });
|
||||
} else if (type === 'font') {
|
||||
|
||||
Reference in new issue
Block a user