Progress
This commit is contained in:
parent
a12209cdec
commit
90d57ccc58
|
@ -105,45 +105,52 @@
|
|||
; ]>
|
||||
; >>>>>
|
||||
|
||||
; <sprite "tt" []
|
||||
; <move <v 0.0 1.6 0.0>
|
||||
; <turtle [
|
||||
; 1 to slen
|
||||
; 0.025 to dlen
|
||||
; 90 U
|
||||
; dlen 10 * F
|
||||
; PenDown
|
||||
; 90 L
|
||||
; [12 L dlen 2 * F] 30 times
|
||||
; 90 R
|
||||
; slen F
|
||||
; SetPen
|
||||
; Home
|
||||
; PenDown
|
||||
; [6 CW dlen F] 240 times
|
||||
; PenUp
|
||||
; ]>>>
|
||||
<sprite "tt2" []
|
||||
<move <v 0.0 1.6 3.0>
|
||||
<color 0.5 0.0 1.0
|
||||
<turtle [
|
||||
1 to slen
|
||||
0.025 to dlen
|
||||
90 U
|
||||
dlen 10 * F
|
||||
PenDown
|
||||
90 L
|
||||
[12 L dlen 2 * F] 30 times
|
||||
90 R
|
||||
slen F
|
||||
SetPen
|
||||
Home
|
||||
PenDown
|
||||
[6 CW dlen F] 240 times
|
||||
PenUp
|
||||
]>>>>
|
||||
|
||||
<sprite "tt" []
|
||||
<move <v 0.0 0.01 0.75>
|
||||
<turtle [
|
||||
1.0 to wallHeight
|
||||
0.1 to wallDepth
|
||||
<rotate <v -0.125 0.0 0.0>
|
||||
<texture ["textures/oak-herringbone-5e80fb40b00c9-1200.jpg"
|
||||
<v 3.0 3.0>
|
||||
<v 0.0 0.0>
|
||||
1.0]
|
||||
<turtle [
|
||||
1.0 to wallHeight
|
||||
0.1 to wallDepth
|
||||
|
||||
90 U
|
||||
PenDown
|
||||
[wallHeight F 90 L wallDepth F 90 L] 2 times
|
||||
SetPen
|
||||
Home
|
||||
90 U
|
||||
PenDown
|
||||
[wallHeight F 90 L wallDepth F 90 L] 2 times
|
||||
SetPen
|
||||
Home
|
||||
|
||||
[ 10 to k k / [dup F] k times drop ] to ff
|
||||
[ 1.414 1 1 PenScale ] to big
|
||||
[ 1 1 1 PenScale ] to normal
|
||||
[ 1 to k k / [dup F] k times drop ] to ff
|
||||
[ 2 / dup R big 0 F R normal 0 F ] to rr
|
||||
|
||||
1 CornerDivisions
|
||||
1 1 1 PenScale
|
||||
PenDown
|
||||
1 ff 90 R 1 ff 90 R 1 ff 90 R 1 ff 90 R
|
||||
PenUp
|
||||
]>>>
|
||||
PenDown
|
||||
1 ff 90 rr 1 ff 90 rr 1 ff 90 rr 1 ff 90 rr
|
||||
PenUp
|
||||
]>>>>>
|
||||
|
||||
; <Exit "y" "lobby">
|
||||
; <sprite "y" []
|
||||
|
|
|
@ -265,7 +265,10 @@ export function buildMesh(
|
|||
const t = new TurtleVM(name, scene, meshSpec.value.program.map(fromJS));
|
||||
t.debug = true;
|
||||
t.exec();
|
||||
return { rootnode: t.container };
|
||||
return {
|
||||
rootnode: t.container,
|
||||
subnodes: Promise.resolve(t.meshes),
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
import {
|
||||
Mesh,
|
||||
MeshBuilder,
|
||||
Plane,
|
||||
Quaternion,
|
||||
Ray,
|
||||
Scene,
|
||||
Vector3,
|
||||
} from '@babylonjs/core/Legacy/legacy';
|
||||
|
@ -47,13 +49,15 @@ const D2R = Math.PI / 180;
|
|||
|
||||
export class TurtleVM extends BaseVM<TurtleVM> {
|
||||
container: Mesh;
|
||||
meshes: Mesh[] = [];
|
||||
|
||||
counter = 0;
|
||||
sideOrientation = Mesh.BACKSIDE; // TODO: see SideOrientation primitive below
|
||||
|
||||
pen = new PenState();
|
||||
pos = new Vector3();
|
||||
q = new Quaternion();
|
||||
cornerDivisions = 0;
|
||||
prevQ = this.q;
|
||||
|
||||
get euler(): Vector3 {
|
||||
return this.q.toEulerAngles();
|
||||
|
@ -76,12 +80,11 @@ export class TurtleVM extends BaseVM<TurtleVM> {
|
|||
}
|
||||
|
||||
setQ(newQ: Quaternion) {
|
||||
if (this.cornerDivisions === 0) {
|
||||
this.q = newQ;
|
||||
} else {
|
||||
this.q = newQ;
|
||||
this.pen.push(this.pos, this.q);
|
||||
}
|
||||
this.q = newQ;
|
||||
}
|
||||
|
||||
resetQ(newQ: Quaternion) {
|
||||
this.q = this.prevQ = newQ;
|
||||
}
|
||||
|
||||
rotate(y: number, x: number, z: number) {
|
||||
|
@ -111,11 +114,12 @@ export class TurtleVM extends BaseVM<TurtleVM> {
|
|||
sideOrientation: this.sideOrientation,
|
||||
});
|
||||
m.parent = this.container;
|
||||
this.meshes.push(m);
|
||||
}
|
||||
}
|
||||
|
||||
export const TurtlePrimitives: Environment<TurtleVM> = Object.assign({}, Primitives, {
|
||||
'Home'() { this.pos = new Vector3(); this.q = new Quaternion(); return []; },
|
||||
'Home'() { this.pos = new Vector3(); this.resetQ(new Quaternion()); return []; },
|
||||
|
||||
'GetPos'() { return [this.pos.asArray()]; },
|
||||
'GetX'() { return [this.pos.x]; },
|
||||
|
@ -137,7 +141,7 @@ export const TurtlePrimitives: Environment<TurtleVM> = Object.assign({}, Primiti
|
|||
'SetRY'(v) { this.q.y = v as number * D2R; return []; },
|
||||
'SetRZ'(v) { this.q.z = v as number * D2R; return []; },
|
||||
'SetHeading'(x, y, z) {
|
||||
this.q = Quaternion.FromEulerAngles(x as number * D2R, y as number * D2R, z as number * D2R);
|
||||
this.resetQ(Quaternion.FromEulerAngles(x as number * D2R, y as number * D2R, z as number * D2R));
|
||||
return [];
|
||||
},
|
||||
|
||||
|
@ -178,6 +182,62 @@ export const TurtlePrimitives: Environment<TurtleVM> = Object.assign({}, Primiti
|
|||
}
|
||||
return [];
|
||||
},
|
||||
|
||||
'CornerDivisions'(n) { this.cornerDivisions = n as number; return []; },
|
||||
} satisfies Environment<TurtleVM>);
|
||||
|
||||
function mitredExtrude(
|
||||
name: string,
|
||||
options: { shape: Vector3[], path: Vector3[], close?: boolean },
|
||||
scene: Scene,
|
||||
): Mesh {
|
||||
const shape = options.shape;
|
||||
const path = options.path;
|
||||
const closed = options.close ?? false;
|
||||
|
||||
function miterNormal(v1: Vector3, v2: Vector3): Vector3 {
|
||||
return Vector3.Cross(Vector3.Cross(v2, v1), v2.subtract(v1));
|
||||
}
|
||||
|
||||
var allPaths = [];
|
||||
|
||||
for (var s = 0; s < shape.length; s++) {
|
||||
let axisZ = path[1].subtract(path[0]).normalize();
|
||||
const axisX = Vector3.Cross(scene.activeCamera!.position, axisZ).normalize();
|
||||
const axisY = Vector3.Cross(axisZ, axisX);
|
||||
let startPoint = path[0].add(axisX.scale(shape[s].x)).add(axisY.scale(shape[s].y));
|
||||
const ribbonPath = [startPoint];
|
||||
for (var p = 0; p < path.length - 2; p++) {
|
||||
const nextAxisZ = path[p + 2].subtract(path[p + 1]).normalize();
|
||||
|
||||
startPoint = startPoint.add(axisZ.scale(new Ray(startPoint, axisZ).intersectsPlane(Plane.FromPositionAndNormal(path[p + 1], miterNormal(axisZ, nextAxisZ)))!));
|
||||
|
||||
ribbonPath.push(startPoint);
|
||||
axisZ = nextAxisZ;
|
||||
}
|
||||
// Last Point
|
||||
if (closed) {
|
||||
let nextAxisZ = path[0].subtract(path[path.length - 1]).normalize();
|
||||
startPoint = startPoint.add(axisZ.scale(new Ray(startPoint, axisZ).intersectsPlane(Plane.FromPositionAndNormal(path[path.length - 1], miterNormal(axisZ, nextAxisZ)))!));
|
||||
|
||||
ribbonPath.push(startPoint);
|
||||
axisZ = nextAxisZ;
|
||||
|
||||
nextAxisZ = path[1].subtract(path[0]).normalize();
|
||||
startPoint = startPoint.add(axisZ.scale(new Ray(startPoint, axisZ).intersectsPlane(Plane.FromPositionAndNormal(path[0], miterNormal(axisZ, nextAxisZ)))!));
|
||||
|
||||
ribbonPath.shift();
|
||||
ribbonPath.unshift(startPoint);
|
||||
} else {
|
||||
startPoint = startPoint.add(axisZ.scale(new Ray(startPoint, axisZ).intersectsPlane(Plane.FromPositionAndNormal(path[path.length - 1], axisZ))!));
|
||||
|
||||
ribbonPath.push(startPoint);
|
||||
}
|
||||
allPaths.push(ribbonPath);
|
||||
}
|
||||
|
||||
return MeshBuilder.CreateRibbon(name, {
|
||||
pathArray: allPaths,
|
||||
sideOrientation: Mesh.DOUBLESIDE,
|
||||
closeArray: true,
|
||||
closePath: closed,
|
||||
}, scene);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue