checkpoint kiri module migration work
This commit is contained in:
parent
e341b98849
commit
7d22cc1029
201 changed files with 41262 additions and 85 deletions
309
src2/kiri-mode/cam/anim-2d-fe.js
Normal file
309
src2/kiri-mode/cam/anim-2d-fe.js
Normal file
|
|
@ -0,0 +1,309 @@
|
|||
/** Copyright Stewart Allen <sa@grid.space> -- All Rights Reserved */
|
||||
|
||||
// UI FRONT END ANIMATION CODE for 2D
|
||||
|
||||
import { api } from '../../kiri/api.js';
|
||||
import { space } from '../../moto/space.js';
|
||||
|
||||
const { client } = api;
|
||||
|
||||
const asLines = false;
|
||||
const asPoints = false;
|
||||
|
||||
let meshes = {},
|
||||
button = {},
|
||||
label = {},
|
||||
unitScale = 1,
|
||||
speedValues = [ 1, 2, 4, 8, 32 ],
|
||||
speedPauses = [ 30, 20, 10, 5, 0 ],
|
||||
speedNames = [ "1x", "2x", "4x", "8x", "!!" ],
|
||||
speedMax = speedValues.length - 1,
|
||||
speedIndex = 0,
|
||||
speed,
|
||||
color = 0,
|
||||
material,
|
||||
origin,
|
||||
posOffset = { x:0, y:0, z:0 };
|
||||
|
||||
export function animate_clear(api) {
|
||||
let { anim } = api.ui;
|
||||
space.platform.showGridBelow(true);
|
||||
client.animate_cleanup();
|
||||
Object.keys(meshes).forEach(id => deleteMesh(id));
|
||||
toggleStock(undefined,true,false);
|
||||
api.uc.setVisible(anim.laba, false);
|
||||
api.uc.setVisible(anim.vala, false);
|
||||
}
|
||||
|
||||
export function animate(api, delay) {
|
||||
let alert = api.alerts.show("building animation");
|
||||
let settings = api.conf.get();
|
||||
client.animate_setup(settings, data => {
|
||||
checkMeshCommands(data);
|
||||
if (!(data && data.mesh_add)) {
|
||||
return;
|
||||
}
|
||||
|
||||
let { anim } = api.ui;
|
||||
Object.assign(button, {
|
||||
replay: anim.replay,
|
||||
play: anim.play,
|
||||
step: anim.step,
|
||||
pause: anim.pause,
|
||||
speed: anim.speed,
|
||||
trans: anim.trans,
|
||||
model: anim.model,
|
||||
shade: anim.shade
|
||||
});
|
||||
Object.assign(label, {
|
||||
progress: anim.progress,
|
||||
speed: anim.labspd,
|
||||
x: anim.valx,
|
||||
y: anim.valy,
|
||||
z: anim.valz,
|
||||
});
|
||||
|
||||
origin = settings.origin;
|
||||
speedIndex = api.local.getInt('cam.anim.speed') || 0;
|
||||
updateSpeed();
|
||||
setTimeout(step, delay || 0);
|
||||
|
||||
button.replay.onclick = replay;
|
||||
button.play.onclick = play;
|
||||
button.step.onclick = step;
|
||||
button.pause.onclick = pause;
|
||||
button.speed.onclick = fast;
|
||||
button.trans.onclick = toggleTrans;
|
||||
button.model.onclick = toggleModel;
|
||||
button.shade.onclick = toggleStock;
|
||||
button.play.style.display = '';
|
||||
button.pause.style.display = 'none';
|
||||
|
||||
api.event.emit('animate', 'CAM');
|
||||
api.alerts.hide(alert);
|
||||
space.platform.showGridBelow(false);
|
||||
toggleTrans(0,api.local.getBoolean('cam.anim.trans', true));
|
||||
toggleModel(0,api.local.getBoolean('cam.anim.model', false));
|
||||
toggleStock(0,api.local.getBoolean('cam.anim.stock', false));
|
||||
});
|
||||
}
|
||||
|
||||
Object.assign(client, {
|
||||
animate(data, ondone) {
|
||||
client.send("animate", data, ondone);
|
||||
},
|
||||
|
||||
animate_setup(settings, ondone) {
|
||||
color = settings.controller.dark ? 0x48607B : 0x607FA4;
|
||||
unitScale = settings.controller.units === 'in' ? 1/25.4 : 1;
|
||||
let flatShading = true,
|
||||
transparent = true,
|
||||
opacity = 0.9,
|
||||
side = THREE.DoubleSide;
|
||||
material = new THREE.MeshPhongMaterial({
|
||||
flatShading,
|
||||
transparent,
|
||||
opacity,
|
||||
color,
|
||||
side
|
||||
});
|
||||
add_red_neg_z(material);
|
||||
client.send("animate_setup", {settings}, ondone);
|
||||
},
|
||||
|
||||
animate_cleanup(data, ondone) {
|
||||
client.send("animate_cleanup", data, ondone);
|
||||
}
|
||||
});
|
||||
|
||||
function meshAdd(id, ind, pos, sab) {
|
||||
const geo = new THREE.BufferGeometry();
|
||||
if (sab) {
|
||||
// use array buffer shared with worker
|
||||
pos = new Float32Array(sab);
|
||||
}
|
||||
geo.setAttribute('position', new THREE.BufferAttribute(pos, 3));
|
||||
if (ind.length) {
|
||||
geo.setIndex(new THREE.BufferAttribute(new Uint32Array(ind), 1));
|
||||
}
|
||||
let mesh;
|
||||
if (asPoints) {
|
||||
const mat = new THREE.PointsMaterial({
|
||||
transparent: true,
|
||||
opacity: 0.75,
|
||||
color: 0x888888,
|
||||
size: 0.3
|
||||
});
|
||||
mesh = new THREE.Points(geo, mat);
|
||||
} else if (asLines) {
|
||||
const mat = new THREE.LineBasicMaterial({
|
||||
transparent: true,
|
||||
opacity: 0.75,
|
||||
color
|
||||
});
|
||||
mesh = new THREE.LineSegments(geo, mat);
|
||||
} else {
|
||||
geo.computeVertexNormals();
|
||||
mesh = new THREE.Mesh(geo, material);
|
||||
mesh.renderOrder = -10;
|
||||
}
|
||||
space.world.add(mesh);
|
||||
meshes[id] = mesh;
|
||||
}
|
||||
|
||||
function meshUpdates(id) {
|
||||
const mesh = meshes[id];
|
||||
if (!mesh) {
|
||||
return; // animate cancelled
|
||||
}
|
||||
mesh.geometry.attributes.position.needsUpdate = true;
|
||||
space.update();
|
||||
}
|
||||
|
||||
function deleteMesh(id) {
|
||||
space.world.remove(meshes[id]);
|
||||
delete meshes[id];
|
||||
}
|
||||
|
||||
function toggleModel(ev,bool) {
|
||||
api.local.toggle('cam.anim.model', bool);
|
||||
api.widgets.all().forEach(w => w.toggleVisibility(bool));
|
||||
}
|
||||
|
||||
function toggleStock(ev,bool,set) {
|
||||
set !== false && api.local.toggle('cam.anim.stock', bool);
|
||||
return api.event.emit('cam.stock.toggle', bool ?? undefined);
|
||||
}
|
||||
|
||||
function toggleTrans(ev,bool) {
|
||||
bool = api.local.toggle('cam.anim.trans', bool);
|
||||
material.transparent = bool;
|
||||
material.needsUpdate = true;
|
||||
}
|
||||
|
||||
function step() {
|
||||
updateSpeed();
|
||||
client.animate({speed, steps: 1}, handleGridUpdate);
|
||||
}
|
||||
|
||||
function play(opts) {
|
||||
const { steps } = opts;
|
||||
updateSpeed();
|
||||
if (steps !== 1) {
|
||||
button.play.style.display = 'none';
|
||||
button.pause.style.display = '';
|
||||
}
|
||||
client.animate({
|
||||
speed,
|
||||
steps: steps || Infinity,
|
||||
pause: speedPauses[speedIndex]
|
||||
}, handleGridUpdate);
|
||||
}
|
||||
|
||||
function fast(opts) {
|
||||
const { steps } = opts;
|
||||
updateSpeed(1);
|
||||
button.play.style.display = 'none';
|
||||
button.pause.style.display = '';
|
||||
client.animate({
|
||||
speed,
|
||||
steps: steps || Infinity,
|
||||
pause: speedPauses[speedIndex]
|
||||
}, handleGridUpdate);
|
||||
}
|
||||
|
||||
function pause() {
|
||||
button.play.style.display = '';
|
||||
button.pause.style.display = 'none';
|
||||
client.animate({speed: 0}, handleGridUpdate);
|
||||
}
|
||||
|
||||
function handleGridUpdate(data) {
|
||||
checkMeshCommands(data);
|
||||
if (data && data.progress) {
|
||||
label.progress.value = (data.progress * 100).toFixed(1);
|
||||
}
|
||||
}
|
||||
|
||||
function updateSpeed(inc = 0) {
|
||||
if (inc === Infinity) {
|
||||
speedIndex = speedMax;
|
||||
} else if (inc > 0) {
|
||||
speedIndex = (speedIndex + inc) % speedValues.length;
|
||||
}
|
||||
api.local.set('cam.anim.speed', speedIndex);
|
||||
speed = speedValues[speedIndex];
|
||||
label.speed.value = speedNames[speedIndex];
|
||||
}
|
||||
|
||||
function replay() {
|
||||
animate_clear(api);
|
||||
setTimeout(() => {
|
||||
animate(api, 50);
|
||||
}, 250);
|
||||
}
|
||||
|
||||
function checkMeshCommands(data) {
|
||||
if (!data) {
|
||||
return;
|
||||
}
|
||||
if (data.mesh_add) {
|
||||
const { id, ind, pos, offset, sab } = data.mesh_add;
|
||||
meshAdd(id, ind, pos, sab);
|
||||
space.refresh();
|
||||
if (offset) {
|
||||
posOffset = offset;
|
||||
}
|
||||
}
|
||||
if (data.mesh_del) {
|
||||
deleteMesh(data.mesh_del);
|
||||
}
|
||||
if (data.mesh_move) {
|
||||
const { id, pos } = data.mesh_move;
|
||||
const mesh = meshes[id];
|
||||
if (mesh) {
|
||||
mesh.position.x = pos.x;
|
||||
mesh.position.y = pos.y;
|
||||
mesh.position.z = pos.z;
|
||||
space.update();
|
||||
}
|
||||
label.x.value = (pos.x - origin.x).toFixed(2);
|
||||
label.y.value = (pos.y + origin.y).toFixed(2);
|
||||
label.z.value = (pos.z - origin.z).toFixed(2);
|
||||
}
|
||||
if (data.mesh_update) {
|
||||
meshUpdates(data.id);
|
||||
}
|
||||
}
|
||||
|
||||
// SHADER: tint points below z=0 with red
|
||||
function add_red_neg_z(material) {
|
||||
material.onBeforeCompile = (shader) => {
|
||||
shader.vertexShader = shader.vertexShader.replace(
|
||||
`#include <worldpos_vertex>`,
|
||||
`
|
||||
#include <worldpos_vertex>
|
||||
vWorldPosition = vec3(transformed);
|
||||
`
|
||||
);
|
||||
|
||||
shader.vertexShader = `
|
||||
varying vec3 vWorldPosition;
|
||||
` + shader.vertexShader;
|
||||
|
||||
shader.fragmentShader = `
|
||||
varying vec3 vWorldPosition;
|
||||
` + shader.fragmentShader;
|
||||
|
||||
shader.fragmentShader = shader.fragmentShader.replace(
|
||||
`#include <dithering_fragment>`,
|
||||
`
|
||||
#include <dithering_fragment>
|
||||
if (vWorldPosition.z < 0.0) {
|
||||
gl_FragColor.rgb += vec3(0.5, 0.0, 0.0); // Add red tint
|
||||
}
|
||||
`
|
||||
);
|
||||
};
|
||||
return material;
|
||||
}
|
||||
Loading…
Reference in a new issue