@rezless/vm 0.6.2 → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/builtins/agents.d.ts +14 -0
- package/dist/builtins/agents.d.ts.map +1 -0
- package/dist/builtins/agents.js +117 -0
- package/dist/builtins/agents.js.map +1 -0
- package/dist/builtins/animation.d.ts +46 -0
- package/dist/builtins/animation.d.ts.map +1 -0
- package/dist/builtins/animation.js +316 -0
- package/dist/builtins/animation.js.map +1 -0
- package/dist/builtins/attachments.d.ts +9 -0
- package/dist/builtins/attachments.d.ts.map +1 -0
- package/dist/builtins/attachments.js +127 -0
- package/dist/builtins/attachments.js.map +1 -0
- package/dist/builtins/base64.d.ts +13 -2
- package/dist/builtins/base64.d.ts.map +1 -1
- package/dist/builtins/base64.js +8 -6
- package/dist/builtins/base64.js.map +1 -1
- package/dist/builtins/camera.d.ts +35 -0
- package/dist/builtins/camera.d.ts.map +1 -0
- package/dist/builtins/camera.js +104 -0
- package/dist/builtins/camera.js.map +1 -0
- package/dist/builtins/collision.d.ts +21 -0
- package/dist/builtins/collision.d.ts.map +1 -0
- package/dist/builtins/collision.js +44 -0
- package/dist/builtins/collision.js.map +1 -0
- package/dist/builtins/controls.d.ts +19 -0
- package/dist/builtins/controls.d.ts.map +1 -0
- package/dist/builtins/controls.js +27 -0
- package/dist/builtins/controls.js.map +1 -0
- package/dist/builtins/damage.d.ts +24 -0
- package/dist/builtins/damage.d.ts.map +1 -0
- package/dist/builtins/damage.js +166 -0
- package/dist/builtins/damage.js.map +1 -0
- package/dist/builtins/detected.d.ts +22 -1
- package/dist/builtins/detected.d.ts.map +1 -1
- package/dist/builtins/detected.js +28 -2
- package/dist/builtins/detected.js.map +1 -1
- package/dist/builtins/dialog.d.ts +23 -0
- package/dist/builtins/dialog.d.ts.map +1 -0
- package/dist/builtins/dialog.js +69 -0
- package/dist/builtins/dialog.js.map +1 -0
- package/dist/builtins/email.d.ts +61 -0
- package/dist/builtins/email.d.ts.map +1 -0
- package/dist/builtins/email.js +121 -0
- package/dist/builtins/email.js.map +1 -0
- package/dist/builtins/environment.d.ts +27 -0
- package/dist/builtins/environment.d.ts.map +1 -0
- package/dist/builtins/environment.js +126 -0
- package/dist/builtins/environment.js.map +1 -0
- package/dist/builtins/experience.d.ts +51 -0
- package/dist/builtins/experience.d.ts.map +1 -0
- package/dist/builtins/experience.js +202 -0
- package/dist/builtins/experience.js.map +1 -0
- package/dist/builtins/game-control.d.ts +17 -0
- package/dist/builtins/game-control.d.ts.map +1 -0
- package/dist/builtins/game-control.js +21 -0
- package/dist/builtins/game-control.js.map +1 -0
- package/dist/builtins/give.d.ts +16 -0
- package/dist/builtins/give.d.ts.map +1 -0
- package/dist/builtins/give.js +137 -0
- package/dist/builtins/give.js.map +1 -0
- package/dist/builtins/ground.d.ts +18 -0
- package/dist/builtins/ground.d.ts.map +1 -0
- package/dist/builtins/ground.js +83 -0
- package/dist/builtins/ground.js.map +1 -0
- package/dist/builtins/hash.d.ts +1 -0
- package/dist/builtins/hash.d.ts.map +1 -1
- package/dist/builtins/hash.js +12 -2
- package/dist/builtins/hash.js.map +1 -1
- package/dist/builtins/http.d.ts +99 -4
- package/dist/builtins/http.d.ts.map +1 -1
- package/dist/builtins/http.js +216 -6
- package/dist/builtins/http.js.map +1 -1
- package/dist/builtins/index.d.ts.map +1 -1
- package/dist/builtins/index.js +250 -14
- package/dist/builtins/index.js.map +1 -1
- package/dist/builtins/inventory.d.ts +8 -5
- package/dist/builtins/inventory.d.ts.map +1 -1
- package/dist/builtins/inventory.js +37 -15
- package/dist/builtins/inventory.js.map +1 -1
- package/dist/builtins/json.d.ts.map +1 -1
- package/dist/builtins/json.js +45 -34
- package/dist/builtins/json.js.map +1 -1
- package/dist/builtins/land.d.ts +29 -0
- package/dist/builtins/land.d.ts.map +1 -0
- package/dist/builtins/land.js +339 -0
- package/dist/builtins/land.js.map +1 -0
- package/dist/builtins/link-info.js +2 -2
- package/dist/builtins/link-info.js.map +1 -1
- package/dist/builtins/links.d.ts +20 -0
- package/dist/builtins/links.d.ts.map +1 -0
- package/dist/builtins/links.js +53 -0
- package/dist/builtins/links.js.map +1 -0
- package/dist/builtins/linksetdata.d.ts +5 -0
- package/dist/builtins/linksetdata.d.ts.map +1 -1
- package/dist/builtins/linksetdata.js +22 -9
- package/dist/builtins/linksetdata.js.map +1 -1
- package/dist/builtins/lists.d.ts +21 -0
- package/dist/builtins/lists.d.ts.map +1 -1
- package/dist/builtins/lists.js +137 -17
- package/dist/builtins/lists.js.map +1 -1
- package/dist/builtins/math.d.ts +18 -0
- package/dist/builtins/math.d.ts.map +1 -1
- package/dist/builtins/math.js +104 -5
- package/dist/builtins/math.js.map +1 -1
- package/dist/builtins/media.d.ts +8 -0
- package/dist/builtins/media.d.ts.map +1 -0
- package/dist/builtins/media.js +167 -0
- package/dist/builtins/media.js.map +1 -0
- package/dist/builtins/motion.d.ts +79 -0
- package/dist/builtins/motion.d.ts.map +1 -0
- package/dist/builtins/motion.js +396 -0
- package/dist/builtins/motion.js.map +1 -0
- package/dist/builtins/notecard-search.d.ts +15 -0
- package/dist/builtins/notecard-search.d.ts.map +1 -0
- package/dist/builtins/notecard-search.js +374 -0
- package/dist/builtins/notecard-search.js.map +1 -0
- package/dist/builtins/object-animation.d.ts +21 -0
- package/dist/builtins/object-animation.d.ts.map +1 -0
- package/dist/builtins/object-animation.js +193 -0
- package/dist/builtins/object-animation.js.map +1 -0
- package/dist/builtins/object-reads.d.ts +39 -0
- package/dist/builtins/object-reads.d.ts.map +1 -0
- package/dist/builtins/object-reads.js +332 -0
- package/dist/builtins/object-reads.js.map +1 -0
- package/dist/builtins/object.d.ts +11 -2
- package/dist/builtins/object.d.ts.map +1 -1
- package/dist/builtins/object.js +32 -8
- package/dist/builtins/object.js.map +1 -1
- package/dist/builtins/particles.d.ts +4 -0
- package/dist/builtins/particles.d.ts.map +1 -0
- package/dist/builtins/particles.js +65 -0
- package/dist/builtins/particles.js.map +1 -0
- package/dist/builtins/pathfinding.d.ts +39 -0
- package/dist/builtins/pathfinding.d.ts.map +1 -0
- package/dist/builtins/pathfinding.js +83 -0
- package/dist/builtins/pathfinding.js.map +1 -0
- package/dist/builtins/permissions.d.ts.map +1 -1
- package/dist/builtins/permissions.js +6 -0
- package/dist/builtins/permissions.js.map +1 -1
- package/dist/builtins/physics.d.ts +49 -0
- package/dist/builtins/physics.d.ts.map +1 -0
- package/dist/builtins/physics.js +47 -0
- package/dist/builtins/physics.js.map +1 -0
- package/dist/builtins/prim-accessors.d.ts +4 -0
- package/dist/builtins/prim-accessors.d.ts.map +1 -1
- package/dist/builtins/prim-accessors.js +75 -28
- package/dist/builtins/prim-accessors.js.map +1 -1
- package/dist/builtins/prim-params.d.ts.map +1 -1
- package/dist/builtins/prim-params.js +6 -2
- package/dist/builtins/prim-params.js.map +1 -1
- package/dist/builtins/raycast.d.ts +3 -0
- package/dist/builtins/raycast.d.ts.map +1 -0
- package/dist/builtins/raycast.js +65 -0
- package/dist/builtins/raycast.js.map +1 -0
- package/dist/builtins/region.d.ts +31 -0
- package/dist/builtins/region.d.ts.map +1 -0
- package/dist/builtins/region.js +125 -0
- package/dist/builtins/region.js.map +1 -0
- package/dist/builtins/remote-load.d.ts +3 -0
- package/dist/builtins/remote-load.d.ts.map +1 -0
- package/dist/builtins/remote-load.js +53 -0
- package/dist/builtins/remote-load.js.map +1 -0
- package/dist/builtins/rez.d.ts +10 -0
- package/dist/builtins/rez.d.ts.map +1 -0
- package/dist/builtins/rez.js +255 -0
- package/dist/builtins/rez.js.map +1 -0
- package/dist/builtins/rsa.d.ts +4 -0
- package/dist/builtins/rsa.d.ts.map +1 -0
- package/dist/builtins/rsa.js +44 -0
- package/dist/builtins/rsa.js.map +1 -0
- package/dist/builtins/script-control.d.ts +8 -3
- package/dist/builtins/script-control.d.ts.map +1 -1
- package/dist/builtins/script-control.js +27 -8
- package/dist/builtins/script-control.js.map +1 -1
- package/dist/builtins/sensor.d.ts +11 -0
- package/dist/builtins/sensor.d.ts.map +1 -0
- package/dist/builtins/sensor.js +145 -0
- package/dist/builtins/sensor.js.map +1 -0
- package/dist/builtins/sit.d.ts +23 -0
- package/dist/builtins/sit.d.ts.map +1 -0
- package/dist/builtins/sit.js +150 -0
- package/dist/builtins/sit.js.map +1 -0
- package/dist/builtins/sound.d.ts +19 -0
- package/dist/builtins/sound.d.ts.map +1 -0
- package/dist/builtins/sound.js +113 -0
- package/dist/builtins/sound.js.map +1 -0
- package/dist/builtins/strings.d.ts +6 -0
- package/dist/builtins/strings.d.ts.map +1 -1
- package/dist/builtins/strings.js +47 -6
- package/dist/builtins/strings.js.map +1 -1
- package/dist/builtins/targets.d.ts +12 -0
- package/dist/builtins/targets.d.ts.map +1 -0
- package/dist/builtins/targets.js +121 -0
- package/dist/builtins/targets.js.map +1 -0
- package/dist/builtins/time.d.ts +15 -5
- package/dist/builtins/time.d.ts.map +1 -1
- package/dist/builtins/time.js +36 -11
- package/dist/builtins/time.js.map +1 -1
- package/dist/builtins/vehicles.d.ts +22 -0
- package/dist/builtins/vehicles.d.ts.map +1 -0
- package/dist/builtins/vehicles.js +78 -0
- package/dist/builtins/vehicles.js.map +1 -0
- package/dist/builtins/viewer.d.ts +39 -0
- package/dist/builtins/viewer.d.ts.map +1 -0
- package/dist/builtins/viewer.js +74 -0
- package/dist/builtins/viewer.js.map +1 -0
- package/dist/clock.d.ts +45 -7
- package/dist/clock.d.ts.map +1 -1
- package/dist/clock.js +125 -14
- package/dist/clock.js.map +1 -1
- package/dist/dispatch.d.ts +3 -2
- package/dist/dispatch.d.ts.map +1 -1
- package/dist/dispatch.js +15 -10
- package/dist/dispatch.js.map +1 -1
- package/dist/experience.d.ts +39 -0
- package/dist/experience.d.ts.map +1 -0
- package/dist/experience.js +38 -0
- package/dist/experience.js.map +1 -0
- package/dist/index.d.ts +20 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/interpreter.d.ts +5 -10
- package/dist/interpreter.d.ts.map +1 -1
- package/dist/interpreter.js +143 -70
- package/dist/interpreter.js.map +1 -1
- package/dist/inventory.d.ts +2 -0
- package/dist/inventory.d.ts.map +1 -1
- package/dist/inventory.js +2 -0
- package/dist/inventory.js.map +1 -1
- package/dist/linkset.d.ts +147 -11
- package/dist/linkset.d.ts.map +1 -1
- package/dist/linkset.js +401 -28
- package/dist/linkset.js.map +1 -1
- package/dist/memory.d.ts +5 -2
- package/dist/memory.d.ts.map +1 -1
- package/dist/memory.js +5 -2
- package/dist/memory.js.map +1 -1
- package/dist/prim-params.d.ts +27 -10
- package/dist/prim-params.d.ts.map +1 -1
- package/dist/prim-params.js +209 -125
- package/dist/prim-params.js.map +1 -1
- package/dist/prim.d.ts +95 -5
- package/dist/prim.d.ts.map +1 -1
- package/dist/prim.js +96 -7
- package/dist/prim.js.map +1 -1
- package/dist/runtime.d.ts +52 -3
- package/dist/runtime.d.ts.map +1 -1
- package/dist/script.d.ts +171 -12
- package/dist/script.d.ts.map +1 -1
- package/dist/script.js +480 -73
- package/dist/script.js.map +1 -1
- package/dist/typecheck.d.ts +3 -1
- package/dist/typecheck.d.ts.map +1 -1
- package/dist/typecheck.js +25 -5
- package/dist/typecheck.js.map +1 -1
- package/dist/values/coerce.d.ts +1 -1
- package/dist/values/coerce.d.ts.map +1 -1
- package/dist/values/coerce.js +10 -6
- package/dist/values/coerce.js.map +1 -1
- package/dist/values/format.d.ts +3 -1
- package/dist/values/format.d.ts.map +1 -1
- package/dist/values/format.js +10 -6
- package/dist/values/format.js.map +1 -1
- package/dist/values/ops.d.ts +3 -0
- package/dist/values/ops.d.ts.map +1 -1
- package/dist/values/ops.js +2 -2
- package/dist/values/ops.js.map +1 -1
- package/dist/world.d.ts +247 -1
- package/dist/world.d.ts.map +1 -1
- package/dist/world.js +318 -6
- package/dist/world.js.map +1 -1
- package/package.json +2 -2
package/dist/prim-params.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { CLICK_ACTION_TOUCH, OVERRIDE_GLTF_BASE_ALPHA, OVERRIDE_GLTF_BASE_ALPHA_MASK, OVERRIDE_GLTF_BASE_ALPHA_MODE, OVERRIDE_GLTF_BASE_COLOR_FACTOR, OVERRIDE_GLTF_BASE_DOUBLE_SIDED, OVERRIDE_GLTF_EMISSIVE_FACTOR, OVERRIDE_GLTF_METALLIC_FACTOR, OVERRIDE_GLTF_ROUGHNESS_FACTOR, PRIM_ALPHA_MODE, PRIM_ALPHA_MODE_BLEND, PRIM_ALPHA_MODE_MASK, PRIM_ALLOW_UNSIT, PRIM_BUMP_NONE, PRIM_BUMP_SHINY, PRIM_CAST_SHADOWS, PRIM_CLICK_ACTION, PRIM_COLOR, PRIM_DAMAGE, PRIM_DESC, PRIM_FLEXIBLE, PRIM_FULLBRIGHT, PRIM_GLOW, PRIM_GLTF_BASE_COLOR, PRIM_GLTF_EMISSIVE, PRIM_GLTF_METALLIC_ROUGHNESS, PRIM_GLTF_NORMAL, PRIM_HEALTH, PRIM_HOLE_DEFAULT, PRIM_LINK_TARGET, PRIM_MATERIAL, PRIM_MATERIAL_WOOD, PRIM_NAME, PRIM_NORMAL, PRIM_OMEGA, PRIM_PHANTOM, PRIM_PHYSICS, PRIM_PHYSICS_SHAPE_PRIM, PRIM_PHYSICS_SHAPE_TYPE, PRIM_POINT_LIGHT, PRIM_POSITION, PRIM_POS_LOCAL, PRIM_PROJECTOR, PRIM_REFLECTION_PROBE, PRIM_RENDER_MATERIAL, PRIM_ROTATION, PRIM_ROT_LOCAL, PRIM_SCRIPTED_SIT_ONLY, PRIM_SCULPT_TYPE_SPHERE, PRIM_SHINY_NONE, PRIM_SIT_FLAGS, PRIM_SIT_TARGET, PRIM_SIZE, PRIM_SLICE, PRIM_SPECULAR, PRIM_TEMP_ON_REZ, PRIM_TEXGEN, PRIM_TEXGEN_DEFAULT, PRIM_TEXT, PRIM_TEXTURE, PRIM_TYPE, PRIM_TYPE_BOX, PRIM_TYPE_CYLINDER, PRIM_TYPE_PRISM, PRIM_TYPE_RING, PRIM_TYPE_SCULPT, PRIM_TYPE_SPHERE, PRIM_TYPE_TORUS, PRIM_TYPE_TUBE, STATUS_PHANTOM, STATUS_PHYSICS, TEXTURE_DEFAULT, } from './generated/constants.js';
|
|
2
2
|
import { NULL_KEY, isRotation, isVector } from './values/types.js';
|
|
3
3
|
import { listElementType } from './values/list-types.js';
|
|
4
|
+
import { InventoryType } from './inventory.js';
|
|
4
5
|
import { truncateUtf8 } from './values/utf8.js';
|
|
5
6
|
/**
|
|
6
7
|
* Typed-literal aliases for the PRIM_TYPE_* constants. The
|
|
@@ -45,18 +46,109 @@ export function defaultFace() {
|
|
|
45
46
|
fullBright: false,
|
|
46
47
|
glow: 0,
|
|
47
48
|
texgen: PRIM_TEXGEN_DEFAULT,
|
|
48
|
-
renderMaterial:
|
|
49
|
-
normal: defaultFaceMaterial(),
|
|
50
|
-
specular: { ...defaultFaceMaterial(), color: one(), glossiness: 51, environment: 0 },
|
|
51
|
-
alphaMode: { mode:
|
|
49
|
+
renderMaterial: NULL_KEY,
|
|
50
|
+
normal: { ...defaultFaceMaterial(), texture: NULL_KEY },
|
|
51
|
+
specular: { ...defaultFaceMaterial(), texture: NULL_KEY, color: one(), glossiness: 51, environment: 0 },
|
|
52
|
+
alphaMode: { mode: PRIM_ALPHA_MODE_BLEND, cutoff: 0 },
|
|
52
53
|
gltf: {
|
|
53
|
-
baseColor: { ...defaultFaceMaterial(), color:
|
|
54
|
+
baseColor: { ...defaultFaceMaterial(), color: '', alpha: '', alphaMode: '', alphaCutoff: '', doubleSided: '' },
|
|
54
55
|
normal: defaultFaceMaterial(),
|
|
55
|
-
metallicRoughness: { ...defaultFaceMaterial(), metallic:
|
|
56
|
-
emissive: { ...defaultFaceMaterial(), tint:
|
|
56
|
+
metallicRoughness: { ...defaultFaceMaterial(), metallic: '', roughness: '' },
|
|
57
|
+
emissive: { ...defaultFaceMaterial(), tint: '' },
|
|
57
58
|
},
|
|
58
59
|
};
|
|
59
60
|
}
|
|
61
|
+
function clearGltfOverrides(g) {
|
|
62
|
+
g.baseColor = { ...g.baseColor, texture: '', color: '', alpha: '', alphaMode: '', alphaCutoff: '', doubleSided: '' };
|
|
63
|
+
g.normal = { ...g.normal, texture: '' };
|
|
64
|
+
g.metallicRoughness = { ...g.metallicRoughness, texture: '', metallic: '', roughness: '' };
|
|
65
|
+
g.emissive = { ...g.emissive, texture: '', tint: '' };
|
|
66
|
+
}
|
|
67
|
+
const UUID = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
68
|
+
const findItem = (prim, type, name) => prim.inventory.find((it) => it.type === type && it.name === name);
|
|
69
|
+
/** The key a render material argument names: "" (none), a key, or a material item's name; null if it names nothing. */
|
|
70
|
+
export function renderMaterialKey(prim, material) {
|
|
71
|
+
if (material === '')
|
|
72
|
+
return NULL_KEY;
|
|
73
|
+
if (UUID.test(material))
|
|
74
|
+
return material;
|
|
75
|
+
return findItem(prim, InventoryType.MATERIAL, material)?.key ?? null;
|
|
76
|
+
}
|
|
77
|
+
export function textureKey(prim, texture) {
|
|
78
|
+
if (texture === '')
|
|
79
|
+
return NULL_KEY;
|
|
80
|
+
if (UUID.test(texture))
|
|
81
|
+
return texture;
|
|
82
|
+
return findItem(prim, InventoryType.TEXTURE, texture)?.key ?? null;
|
|
83
|
+
}
|
|
84
|
+
const itemName = (prim, type, key) => key === NULL_KEY ? key : (prim.inventory.find((it) => it.type === type && it.key === key)?.name ?? key);
|
|
85
|
+
export const textureName = (prim, key) => itemName(prim, InventoryType.TEXTURE, key);
|
|
86
|
+
export const materialName = (prim, key) => itemName(prim, InventoryType.MATERIAL, key);
|
|
87
|
+
const OVERRIDE_TYPES = {
|
|
88
|
+
[OVERRIDE_GLTF_BASE_COLOR_FACTOR]: 'vector',
|
|
89
|
+
[OVERRIDE_GLTF_BASE_ALPHA]: 'float',
|
|
90
|
+
[OVERRIDE_GLTF_BASE_ALPHA_MODE]: 'integer',
|
|
91
|
+
[OVERRIDE_GLTF_BASE_ALPHA_MASK]: 'float',
|
|
92
|
+
[OVERRIDE_GLTF_BASE_DOUBLE_SIDED]: 'integer',
|
|
93
|
+
[OVERRIDE_GLTF_METALLIC_FACTOR]: 'float',
|
|
94
|
+
[OVERRIDE_GLTF_ROUGHNESS_FACTOR]: 'float',
|
|
95
|
+
[OVERRIDE_GLTF_EMISSIVE_FACTOR]: 'vector',
|
|
96
|
+
};
|
|
97
|
+
const overrideType = (code) => (typeof code === 'number' ? OVERRIDE_TYPES[code] : undefined);
|
|
98
|
+
/**
|
|
99
|
+
* Apply llSetLinkGLTFOverrides' [OVERRIDE_GLTF_*, value, ...] pairs. The base
|
|
100
|
+
* colour and alpha form one factor that "" leaves alone; "" clears the others.
|
|
101
|
+
* One wrong-typed value rejects the whole call; an unknown code is skipped.
|
|
102
|
+
*/
|
|
103
|
+
export function setGltfOverrides(g, params) {
|
|
104
|
+
for (let i = 0; i + 1 < params.length; i += 2) {
|
|
105
|
+
const expected = overrideType(params[i]);
|
|
106
|
+
if (expected === undefined || params[i + 1] === '')
|
|
107
|
+
continue;
|
|
108
|
+
const given = givenType(params, i + 1);
|
|
109
|
+
if (given !== expected && !(expected === 'float' && given === 'integer'))
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
112
|
+
const bc = g.baseColor;
|
|
113
|
+
for (let i = 0; i + 1 < params.length; i += 2) {
|
|
114
|
+
const v = params[i + 1];
|
|
115
|
+
const n = typeof v === 'number' ? v : '';
|
|
116
|
+
switch (params[i]) {
|
|
117
|
+
case OVERRIDE_GLTF_BASE_COLOR_FACTOR:
|
|
118
|
+
if (isVector(v)) {
|
|
119
|
+
bc.color = clampVec(asVec(v), 0, 1);
|
|
120
|
+
if (bc.alpha === '')
|
|
121
|
+
bc.alpha = 1;
|
|
122
|
+
}
|
|
123
|
+
break;
|
|
124
|
+
case OVERRIDE_GLTF_BASE_ALPHA:
|
|
125
|
+
if (typeof v === 'number') {
|
|
126
|
+
bc.alpha = clamp(v, 0, 1);
|
|
127
|
+
if (bc.color === '')
|
|
128
|
+
bc.color = one();
|
|
129
|
+
}
|
|
130
|
+
break;
|
|
131
|
+
case OVERRIDE_GLTF_BASE_ALPHA_MODE:
|
|
132
|
+
bc.alphaMode = n === '' ? '' : clamp(n, 0, 2);
|
|
133
|
+
break;
|
|
134
|
+
case OVERRIDE_GLTF_BASE_ALPHA_MASK:
|
|
135
|
+
bc.alphaCutoff = n === '' ? '' : clamp(n, 0, 1);
|
|
136
|
+
break;
|
|
137
|
+
case OVERRIDE_GLTF_BASE_DOUBLE_SIDED:
|
|
138
|
+
bc.doubleSided = n === '' ? '' : clamp(n, 0, 1);
|
|
139
|
+
break;
|
|
140
|
+
case OVERRIDE_GLTF_METALLIC_FACTOR:
|
|
141
|
+
g.metallicRoughness.metallic = n === '' ? '' : clamp(n, 0, 1);
|
|
142
|
+
break;
|
|
143
|
+
case OVERRIDE_GLTF_ROUGHNESS_FACTOR:
|
|
144
|
+
g.metallicRoughness.roughness = n === '' ? '' : clamp(n, 0, 1);
|
|
145
|
+
break;
|
|
146
|
+
case OVERRIDE_GLTF_EMISSIVE_FACTOR:
|
|
147
|
+
g.emissive.tint = isVector(v) ? clampVec(asVec(v), 0, 1) : '';
|
|
148
|
+
break;
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
}
|
|
60
152
|
export function defaultShape() {
|
|
61
153
|
return {
|
|
62
154
|
kind: SHAPE_BOX,
|
|
@@ -74,7 +166,7 @@ export function defaultPrimParams() {
|
|
|
74
166
|
rotation: identityRot(),
|
|
75
167
|
size: { x: 0.5, y: 0.5, z: 0.5 },
|
|
76
168
|
faces: Array.from({ length: 6 }, () => defaultFace()),
|
|
77
|
-
pointLight: { enabled: false, color:
|
|
169
|
+
pointLight: { enabled: false, color: zero(), intensity: 0, radius: 0, falloff: 0 },
|
|
78
170
|
glow: [0, 0, 0, 0, 0, 0],
|
|
79
171
|
omega: { axis: zero(), spinrate: 0, gain: 0 },
|
|
80
172
|
physicsShapeType: PRIM_PHYSICS_SHAPE_PRIM,
|
|
@@ -92,7 +184,7 @@ export function defaultPrimParams() {
|
|
|
92
184
|
projector: { texture: NULL_KEY, fov: 0, focus: 0, ambiance: 0 },
|
|
93
185
|
clickAction: CLICK_ACTION_TOUCH,
|
|
94
186
|
damage: { amount: 0, type: 0 },
|
|
95
|
-
health:
|
|
187
|
+
health: 0,
|
|
96
188
|
reflectionProbe: { enabled: false, ambiance: 0, clipDistance: 0, flags: 0 },
|
|
97
189
|
physicsMaterial: { gravityMultiplier: 1, restitution: 0.5, friction: Math.fround(0.6), density: 1000 },
|
|
98
190
|
textureAnim: { mode: 0, face: 0, sizex: 0, sizey: 0, start: 0, length: 0, rate: 0 },
|
|
@@ -128,11 +220,11 @@ function normalizeRot(r) {
|
|
|
128
220
|
return identityRot();
|
|
129
221
|
return { x: r.x / mag, y: r.y / mag, z: r.z / mag, s: r.s / mag };
|
|
130
222
|
}
|
|
131
|
-
/** Face indexes a face argument names: every face for
|
|
223
|
+
/** Face indexes a face argument names: every face for a negative face, none past the shape's face count. */
|
|
132
224
|
export function faceIndices(p, face) {
|
|
133
|
-
if (face
|
|
225
|
+
if (face < 0)
|
|
134
226
|
return p.faces.map((_, i) => i);
|
|
135
|
-
return face
|
|
227
|
+
return face < p.faces.length ? [face] : [];
|
|
136
228
|
}
|
|
137
229
|
const facesOf = (p, faceArg) => faceIndices(p, num(faceArg, 0) | 0);
|
|
138
230
|
/**
|
|
@@ -214,20 +306,23 @@ export function writePrimParamSlots(param, rules, cursor) {
|
|
|
214
306
|
* advances by `1 + consumed`). Returns `null` for unsupported / unknown
|
|
215
307
|
* rule constants — the walker stops parsing the list, matching LSL.
|
|
216
308
|
*/
|
|
217
|
-
export function writePrimParam(prim, param, rules, cursor) {
|
|
309
|
+
export function writePrimParam(prim, param, rules, cursor, caller = prim) {
|
|
218
310
|
const p = prim.params;
|
|
219
311
|
switch (param) {
|
|
220
312
|
case PRIM_NAME:
|
|
221
|
-
prim.name = truncateUtf8(str(rules[cursor]), 63);
|
|
313
|
+
prim.name = truncateUtf8(plainText(str(rules[cursor])), 63);
|
|
222
314
|
return 1;
|
|
223
315
|
case PRIM_DESC:
|
|
224
|
-
prim.description = truncateUtf8(str(rules[cursor]), 127);
|
|
316
|
+
prim.description = truncateUtf8(plainText(str(rules[cursor])), 127);
|
|
225
317
|
prim.appearance.description = prim.description;
|
|
226
318
|
return 1;
|
|
227
319
|
case PRIM_TEXT: {
|
|
228
320
|
const text = truncateUtf8(str(rules[cursor]), 254);
|
|
229
321
|
const color = asVec(rules[cursor + 1]);
|
|
230
322
|
const alpha = num(rules[cursor + 2], 1);
|
|
323
|
+
const outOfRange = (v) => v < 0 || v > 1;
|
|
324
|
+
if (outOfRange(alpha) || outOfRange(color.x) || outOfRange(color.y) || outOfRange(color.z))
|
|
325
|
+
return 3;
|
|
231
326
|
prim.appearance.text = { text, color, alpha };
|
|
232
327
|
return 3;
|
|
233
328
|
}
|
|
@@ -256,6 +351,7 @@ export function writePrimParam(prim, param, rules, cursor) {
|
|
|
256
351
|
return 1;
|
|
257
352
|
case PRIM_TEMP_ON_REZ:
|
|
258
353
|
p.tempOnRez = num(rules[cursor]) !== 0;
|
|
354
|
+
prim.linkset?.setTemporary(p.tempOnRez);
|
|
259
355
|
return 1;
|
|
260
356
|
case PRIM_PHYSICS_SHAPE_TYPE:
|
|
261
357
|
p.physicsShapeType = num(rules[cursor]) | 0;
|
|
@@ -281,9 +377,16 @@ export function writePrimParam(prim, param, rules, cursor) {
|
|
|
281
377
|
case PRIM_DAMAGE:
|
|
282
378
|
p.damage = { amount: num(rules[cursor]), type: num(rules[cursor + 1]) | 0 };
|
|
283
379
|
return 2;
|
|
284
|
-
case PRIM_OMEGA:
|
|
285
|
-
|
|
380
|
+
case PRIM_OMEGA: {
|
|
381
|
+
const axis = asVec(rules[cursor]);
|
|
382
|
+
const length = Math.hypot(axis.x, axis.y, axis.z) || 1;
|
|
383
|
+
p.omega = {
|
|
384
|
+
axis: { x: axis.x / length, y: axis.y / length, z: axis.z / length },
|
|
385
|
+
spinrate: num(rules[cursor + 1]) * length,
|
|
386
|
+
gain: num(rules[cursor + 2]),
|
|
387
|
+
};
|
|
286
388
|
return 3;
|
|
389
|
+
}
|
|
287
390
|
case PRIM_POINT_LIGHT:
|
|
288
391
|
p.pointLight = {
|
|
289
392
|
enabled: num(rules[cursor]) !== 0,
|
|
@@ -341,29 +444,33 @@ export function writePrimParam(prim, param, rules, cursor) {
|
|
|
341
444
|
}
|
|
342
445
|
case PRIM_TEXTURE: {
|
|
343
446
|
const faces = facesOf(p, rules[cursor]);
|
|
344
|
-
const tex = str(rules[cursor + 1]);
|
|
447
|
+
const tex = textureKey(caller, str(rules[cursor + 1])) ?? NULL_KEY;
|
|
345
448
|
const repeats = asVec(rules[cursor + 2]);
|
|
346
449
|
const offsets = asVec(rules[cursor + 3]);
|
|
347
450
|
const rot = num(rules[cursor + 4]);
|
|
348
451
|
for (const f of faces) {
|
|
349
452
|
p.faces[f].texture = tex;
|
|
350
|
-
p.faces[f].textureRepeats = { x: repeats.x, y: repeats.y, z:
|
|
351
|
-
p.faces[f].textureOffsets = { x: offsets.x, y: offsets.y, z:
|
|
453
|
+
p.faces[f].textureRepeats = { x: repeats.x, y: repeats.y, z: 0 };
|
|
454
|
+
p.faces[f].textureOffsets = { x: offsets.x, y: offsets.y, z: 0 };
|
|
352
455
|
p.faces[f].textureRotation = rot;
|
|
353
456
|
}
|
|
354
457
|
return 5;
|
|
355
458
|
}
|
|
356
459
|
case PRIM_RENDER_MATERIAL: {
|
|
357
460
|
const faces = facesOf(p, rules[cursor]);
|
|
358
|
-
const m = str(rules[cursor + 1]);
|
|
461
|
+
const m = renderMaterialKey(caller, str(rules[cursor + 1])) ?? NULL_KEY;
|
|
359
462
|
for (const f of faces) {
|
|
360
463
|
p.faces[f].renderMaterial = m;
|
|
464
|
+
clearGltfOverrides(p.faces[f].gltf);
|
|
361
465
|
}
|
|
362
466
|
return 2;
|
|
363
467
|
}
|
|
364
468
|
case PRIM_FULLBRIGHT: {
|
|
365
469
|
const faces = facesOf(p, rules[cursor]);
|
|
366
|
-
const
|
|
470
|
+
const raw = num(rules[cursor + 1]);
|
|
471
|
+
if (raw !== 0 && raw !== 1)
|
|
472
|
+
return 2;
|
|
473
|
+
const v = raw === 1;
|
|
367
474
|
for (const f of faces) {
|
|
368
475
|
p.faces[f].fullBright = v;
|
|
369
476
|
}
|
|
@@ -382,6 +489,8 @@ export function writePrimParam(prim, param, rules, cursor) {
|
|
|
382
489
|
const faces = facesOf(p, rules[cursor]);
|
|
383
490
|
const shiny = num(rules[cursor + 1]) | 0;
|
|
384
491
|
const bump = num(rules[cursor + 2]) | 0;
|
|
492
|
+
if (shiny < 0 || shiny > 3 || bump < 0 || bump > 17)
|
|
493
|
+
return 3;
|
|
385
494
|
for (const f of faces) {
|
|
386
495
|
p.faces[f].bumpShiny = { shiny, bump };
|
|
387
496
|
}
|
|
@@ -390,6 +499,8 @@ export function writePrimParam(prim, param, rules, cursor) {
|
|
|
390
499
|
case PRIM_TEXGEN: {
|
|
391
500
|
const faces = facesOf(p, rules[cursor]);
|
|
392
501
|
const mode = num(rules[cursor + 1]) | 0;
|
|
502
|
+
if (mode < 0 || mode > 1)
|
|
503
|
+
return 2;
|
|
393
504
|
for (const f of faces) {
|
|
394
505
|
p.faces[f].texgen = mode;
|
|
395
506
|
}
|
|
@@ -398,12 +509,13 @@ export function writePrimParam(prim, param, rules, cursor) {
|
|
|
398
509
|
case PRIM_NORMAL: {
|
|
399
510
|
const faces = facesOf(p, rules[cursor]);
|
|
400
511
|
const tex = str(rules[cursor + 1]);
|
|
401
|
-
const
|
|
402
|
-
const
|
|
403
|
-
const
|
|
512
|
+
const key = textureKey(caller, tex) ?? NULL_KEY;
|
|
513
|
+
const repeats = tex === '' ? { x: 1, y: 1, z: 0 } : asVec(rules[cursor + 2]);
|
|
514
|
+
const offsets = tex === '' ? zero() : asVec(rules[cursor + 3]);
|
|
515
|
+
const rot = tex === '' ? 0 : num(rules[cursor + 4]);
|
|
404
516
|
for (const f of faces) {
|
|
405
517
|
p.faces[f].normal = {
|
|
406
|
-
texture:
|
|
518
|
+
texture: key,
|
|
407
519
|
textureRepeats: { x: repeats.x, y: repeats.y, z: repeats.z },
|
|
408
520
|
textureOffsets: { x: offsets.x, y: offsets.y, z: offsets.z },
|
|
409
521
|
textureRotation: rot,
|
|
@@ -414,15 +526,17 @@ export function writePrimParam(prim, param, rules, cursor) {
|
|
|
414
526
|
case PRIM_SPECULAR: {
|
|
415
527
|
const faces = facesOf(p, rules[cursor]);
|
|
416
528
|
const tex = str(rules[cursor + 1]);
|
|
417
|
-
const
|
|
418
|
-
const
|
|
419
|
-
const
|
|
420
|
-
const
|
|
421
|
-
const
|
|
422
|
-
const
|
|
529
|
+
const key = textureKey(caller, tex) ?? NULL_KEY;
|
|
530
|
+
const reset = tex === '';
|
|
531
|
+
const repeats = reset ? { x: 1, y: 1, z: 0 } : asVec(rules[cursor + 2]);
|
|
532
|
+
const offsets = reset ? zero() : asVec(rules[cursor + 3]);
|
|
533
|
+
const rot = reset ? 0 : num(rules[cursor + 4]);
|
|
534
|
+
const color = reset ? one() : asVec(rules[cursor + 5]);
|
|
535
|
+
const gloss = reset ? 51 : clamp(num(rules[cursor + 6]) | 0, 0, 255);
|
|
536
|
+
const env = reset ? 0 : clamp(num(rules[cursor + 7]) | 0, 0, 255);
|
|
423
537
|
for (const f of faces) {
|
|
424
538
|
p.faces[f].specular = {
|
|
425
|
-
texture:
|
|
539
|
+
texture: key,
|
|
426
540
|
textureRepeats: { x: repeats.x, y: repeats.y, z: repeats.z },
|
|
427
541
|
textureOffsets: { x: offsets.x, y: offsets.y, z: offsets.z },
|
|
428
542
|
// Second Life stores a negative rotation as 0 and the colour in 8 bits per channel
|
|
@@ -436,99 +550,66 @@ export function writePrimParam(prim, param, rules, cursor) {
|
|
|
436
550
|
}
|
|
437
551
|
case PRIM_ALPHA_MODE: {
|
|
438
552
|
const faces = facesOf(p, rules[cursor]);
|
|
439
|
-
const mode = num(rules[cursor + 1]) | 0;
|
|
440
|
-
const cutoff = num(rules[cursor + 2]) | 0;
|
|
553
|
+
const mode = clamp(num(rules[cursor + 1]) | 0, 0, 3);
|
|
554
|
+
const cutoff = mode === PRIM_ALPHA_MODE_MASK ? clamp(num(rules[cursor + 2]) | 0, 0, 255) : 0;
|
|
441
555
|
for (const f of faces) {
|
|
442
556
|
p.faces[f].alphaMode = { mode, cutoff };
|
|
443
557
|
}
|
|
444
558
|
return 3;
|
|
445
559
|
}
|
|
446
560
|
case PRIM_GLTF_BASE_COLOR: {
|
|
447
|
-
const
|
|
448
|
-
const
|
|
449
|
-
const
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
for (const f of faces) {
|
|
458
|
-
p.faces[f].gltf.baseColor = {
|
|
459
|
-
texture: tex,
|
|
460
|
-
textureRepeats: { x: repeats.x, y: repeats.y, z: repeats.z },
|
|
461
|
-
textureOffsets: { x: offsets.x, y: offsets.y, z: offsets.z },
|
|
462
|
-
textureRotation: rot,
|
|
463
|
-
color: { x: color.x, y: color.y, z: color.z },
|
|
464
|
-
alpha,
|
|
465
|
-
alphaMode: aMode,
|
|
466
|
-
alphaCutoff: aCut,
|
|
467
|
-
doubleSided: dbl,
|
|
468
|
-
};
|
|
469
|
-
}
|
|
561
|
+
const color = rules[cursor + 5];
|
|
562
|
+
const alpha = rules[cursor + 6];
|
|
563
|
+
const factor = color !== '' || alpha !== '';
|
|
564
|
+
writeGltf(prim, caller, rules, cursor, 'baseColor', {
|
|
565
|
+
color: factor ? (color === '' ? one() : clampVec(asVec(color), 0, 1)) : '',
|
|
566
|
+
alpha: factor ? clamp(num(alpha, 1), 0, 1) : '',
|
|
567
|
+
alphaMode: valueOverride(rules[cursor + 7], (v) => clamp(num(v) | 0, 0, 2)),
|
|
568
|
+
alphaCutoff: valueOverride(rules[cursor + 8], (v) => clamp(num(v), 0, 1)),
|
|
569
|
+
doubleSided: valueOverride(rules[cursor + 9], (v) => clamp(num(v) | 0, 0, 1)),
|
|
570
|
+
});
|
|
470
571
|
return 10;
|
|
471
572
|
}
|
|
472
|
-
case PRIM_GLTF_NORMAL:
|
|
473
|
-
|
|
474
|
-
const tex = str(rules[cursor + 1]);
|
|
475
|
-
const repeats = asVec(rules[cursor + 2]);
|
|
476
|
-
const offsets = asVec(rules[cursor + 3]);
|
|
477
|
-
const rot = num(rules[cursor + 4]);
|
|
478
|
-
for (const f of faces) {
|
|
479
|
-
p.faces[f].gltf.normal = {
|
|
480
|
-
texture: tex,
|
|
481
|
-
textureRepeats: { x: repeats.x, y: repeats.y, z: repeats.z },
|
|
482
|
-
textureOffsets: { x: offsets.x, y: offsets.y, z: offsets.z },
|
|
483
|
-
textureRotation: rot,
|
|
484
|
-
};
|
|
485
|
-
}
|
|
573
|
+
case PRIM_GLTF_NORMAL:
|
|
574
|
+
writeGltf(prim, caller, rules, cursor, 'normal', {});
|
|
486
575
|
return 5;
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
const offsets = asVec(rules[cursor + 3]);
|
|
493
|
-
const rot = num(rules[cursor + 4]);
|
|
494
|
-
const metallic = num(rules[cursor + 5]);
|
|
495
|
-
const rough = num(rules[cursor + 6]);
|
|
496
|
-
for (const f of faces) {
|
|
497
|
-
p.faces[f].gltf.metallicRoughness = {
|
|
498
|
-
texture: tex,
|
|
499
|
-
textureRepeats: { x: repeats.x, y: repeats.y, z: repeats.z },
|
|
500
|
-
textureOffsets: { x: offsets.x, y: offsets.y, z: offsets.z },
|
|
501
|
-
textureRotation: rot,
|
|
502
|
-
metallic,
|
|
503
|
-
roughness: rough,
|
|
504
|
-
};
|
|
505
|
-
}
|
|
576
|
+
case PRIM_GLTF_METALLIC_ROUGHNESS:
|
|
577
|
+
writeGltf(prim, caller, rules, cursor, 'metallicRoughness', {
|
|
578
|
+
metallic: valueOverride(rules[cursor + 5], (v) => clamp(num(v), 0, 1)),
|
|
579
|
+
roughness: valueOverride(rules[cursor + 6], (v) => clamp(num(v), 0, 1)),
|
|
580
|
+
});
|
|
506
581
|
return 7;
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
const faces = facesOf(p, rules[cursor]);
|
|
510
|
-
const tex = str(rules[cursor + 1]);
|
|
511
|
-
const repeats = asVec(rules[cursor + 2]);
|
|
512
|
-
const offsets = asVec(rules[cursor + 3]);
|
|
513
|
-
const rot = num(rules[cursor + 4]);
|
|
514
|
-
const tint = asVec(rules[cursor + 5]);
|
|
515
|
-
for (const f of faces) {
|
|
516
|
-
p.faces[f].gltf.emissive = {
|
|
517
|
-
texture: tex,
|
|
518
|
-
textureRepeats: { x: repeats.x, y: repeats.y, z: repeats.z },
|
|
519
|
-
textureOffsets: { x: offsets.x, y: offsets.y, z: offsets.z },
|
|
520
|
-
textureRotation: rot,
|
|
521
|
-
tint: { x: tint.x, y: tint.y, z: tint.z },
|
|
522
|
-
};
|
|
523
|
-
}
|
|
582
|
+
case PRIM_GLTF_EMISSIVE:
|
|
583
|
+
writeGltf(prim, caller, rules, cursor, 'emissive', { tint: valueOverride(rules[cursor + 5], (v) => clampVec(asVec(v), 0, 1)) });
|
|
524
584
|
return 6;
|
|
525
|
-
}
|
|
526
585
|
case PRIM_LINK_TARGET:
|
|
527
586
|
return null;
|
|
528
587
|
default:
|
|
529
588
|
return null;
|
|
530
589
|
}
|
|
531
590
|
}
|
|
591
|
+
const valueOverride = (v, read) => (v === '' ? '' : read(v));
|
|
592
|
+
/**
|
|
593
|
+
* Write one PRIM_GLTF_* rule. "" in a transform slot resets it; "" in a texture
|
|
594
|
+
* or value slot unsets that override. Faces without a render material keep
|
|
595
|
+
* only the transforms.
|
|
596
|
+
*/
|
|
597
|
+
function writeGltf(prim, caller, rules, cursor, rule, values) {
|
|
598
|
+
const transform = {
|
|
599
|
+
textureRepeats: rules[cursor + 2] === '' ? { x: 1, y: 1, z: 0 } : asVec(rules[cursor + 2]),
|
|
600
|
+
textureOffsets: asVec(rules[cursor + 3]),
|
|
601
|
+
textureRotation: num(rules[cursor + 4]),
|
|
602
|
+
};
|
|
603
|
+
const name = str(rules[cursor + 1]);
|
|
604
|
+
const texture = name === '' ? '' : (textureKey(caller, name) ?? NULL_KEY);
|
|
605
|
+
for (const f of facesOf(prim.params, rules[cursor])) {
|
|
606
|
+
const face = prim.params.faces[f];
|
|
607
|
+
const overrides = face.renderMaterial === NULL_KEY ? {} : { texture, ...values };
|
|
608
|
+
face.gltf[rule] = { ...face.gltf[rule], ...transform, ...overrides };
|
|
609
|
+
}
|
|
610
|
+
}
|
|
611
|
+
/** Names and descriptions can't hold the separator characters; they become `?`. */
|
|
612
|
+
const plainText = (s) => s.replace(/[|\n]/g, '?');
|
|
532
613
|
function writePrimType(p, rules, cursor) {
|
|
533
614
|
const kind = (num(rules[cursor]) | 0);
|
|
534
615
|
const old = p.shape;
|
|
@@ -606,7 +687,7 @@ export function readPrimParam(prim, param, rules, cursor) {
|
|
|
606
687
|
return { values: [prim.description], consumed: 0 };
|
|
607
688
|
case PRIM_TEXT: {
|
|
608
689
|
const t = prim.appearance.text;
|
|
609
|
-
return { values: t ? [t.text, t.color, t.alpha] : ['', zero(),
|
|
690
|
+
return { values: t ? [t.text, t.color, t.alpha] : ['', zero(), 1], consumed: 0 };
|
|
610
691
|
}
|
|
611
692
|
case PRIM_POSITION:
|
|
612
693
|
return { values: [prim.regionPosition()], consumed: 0 };
|
|
@@ -683,7 +764,7 @@ export function readPrimParam(prim, param, rules, cursor) {
|
|
|
683
764
|
const out = [];
|
|
684
765
|
for (const f of faces) {
|
|
685
766
|
const fa = p.faces[f];
|
|
686
|
-
out.push(fa.texture, fa.textureRepeats, fa.textureOffsets, fa.textureRotation);
|
|
767
|
+
out.push(textureName(prim, fa.texture), fa.textureRepeats, fa.textureOffsets, fa.textureRotation);
|
|
687
768
|
}
|
|
688
769
|
return { values: out, consumed: 1 };
|
|
689
770
|
}
|
|
@@ -691,7 +772,7 @@ export function readPrimParam(prim, param, rules, cursor) {
|
|
|
691
772
|
const faces = facesOf(p, rules[cursor]);
|
|
692
773
|
const out = [];
|
|
693
774
|
for (const f of faces) {
|
|
694
|
-
out.push(p.faces[f].renderMaterial);
|
|
775
|
+
out.push(materialName(prim, p.faces[f].renderMaterial));
|
|
695
776
|
}
|
|
696
777
|
return { values: out, consumed: 1 };
|
|
697
778
|
}
|
|
@@ -732,7 +813,7 @@ export function readPrimParam(prim, param, rules, cursor) {
|
|
|
732
813
|
const out = [];
|
|
733
814
|
for (const f of faces) {
|
|
734
815
|
const n = p.faces[f].normal;
|
|
735
|
-
out.push(n.texture, n.textureRepeats, n.textureOffsets, n.textureRotation);
|
|
816
|
+
out.push(textureName(prim, n.texture), n.textureRepeats, n.textureOffsets, n.textureRotation);
|
|
736
817
|
}
|
|
737
818
|
return { values: out, consumed: 1 };
|
|
738
819
|
}
|
|
@@ -741,7 +822,7 @@ export function readPrimParam(prim, param, rules, cursor) {
|
|
|
741
822
|
const out = [];
|
|
742
823
|
for (const f of faces) {
|
|
743
824
|
const s = p.faces[f].specular;
|
|
744
|
-
out.push(s.texture, s.textureRepeats, s.textureOffsets, s.textureRotation, s.color, s.glossiness, s.environment);
|
|
825
|
+
out.push(textureName(prim, s.texture), s.textureRepeats, s.textureOffsets, s.textureRotation, s.color, s.glossiness, s.environment);
|
|
745
826
|
}
|
|
746
827
|
return { values: out, consumed: 1 };
|
|
747
828
|
}
|
|
@@ -812,6 +893,7 @@ function readPrimType(p) {
|
|
|
812
893
|
return [];
|
|
813
894
|
}
|
|
814
895
|
const MATERIAL_TYPES = ['string', 'vector', 'vector', 'float'];
|
|
896
|
+
const MAP_TYPES = ['key', 'vector', 'vector', 'float'];
|
|
815
897
|
/**
|
|
816
898
|
* LSL types of the values each PRIM_* rule reads. Per-face rules list one
|
|
817
899
|
* face's values; the pattern repeats for each face.
|
|
@@ -851,13 +933,13 @@ const PRIM_PARAM_TYPES = {
|
|
|
851
933
|
[PRIM_GLOW]: ['float'],
|
|
852
934
|
[PRIM_BUMP_SHINY]: ['integer', 'integer'],
|
|
853
935
|
[PRIM_TEXGEN]: ['integer'],
|
|
854
|
-
[PRIM_NORMAL]:
|
|
855
|
-
[PRIM_SPECULAR]: [...
|
|
936
|
+
[PRIM_NORMAL]: MAP_TYPES,
|
|
937
|
+
[PRIM_SPECULAR]: [...MAP_TYPES, 'vector', 'integer', 'integer'],
|
|
856
938
|
[PRIM_ALPHA_MODE]: ['integer', 'integer'],
|
|
857
|
-
[PRIM_GLTF_BASE_COLOR]: [...
|
|
858
|
-
[PRIM_GLTF_NORMAL]:
|
|
859
|
-
[PRIM_GLTF_METALLIC_ROUGHNESS]: [...
|
|
860
|
-
[PRIM_GLTF_EMISSIVE]: [...
|
|
939
|
+
[PRIM_GLTF_BASE_COLOR]: [...MAP_TYPES, 'vector', 'float', 'integer', 'float', 'integer'],
|
|
940
|
+
[PRIM_GLTF_NORMAL]: MAP_TYPES,
|
|
941
|
+
[PRIM_GLTF_METALLIC_ROUGHNESS]: [...MAP_TYPES, 'float', 'float'],
|
|
942
|
+
[PRIM_GLTF_EMISSIVE]: [...MAP_TYPES, 'vector'],
|
|
861
943
|
};
|
|
862
944
|
/** LSL types of PRIM_TYPE's values, which depend on the shape. */
|
|
863
945
|
function primTypeTypes(kind) {
|
|
@@ -871,10 +953,12 @@ function primTypeTypes(kind) {
|
|
|
871
953
|
}
|
|
872
954
|
return [...common, 'vector', 'vector'];
|
|
873
955
|
}
|
|
956
|
+
/** GLTF override rules take "" in any slot after the face to mean "no override", and read an unset one as "". */
|
|
957
|
+
const GLTF_RULES = new Set([PRIM_GLTF_BASE_COLOR, PRIM_GLTF_NORMAL, PRIM_GLTF_METALLIC_ROUGHNESS, PRIM_GLTF_EMISSIVE]);
|
|
874
958
|
/** LSL types of the values `readPrimParam` returns for `param`. */
|
|
875
959
|
export function primParamTypes(param, values) {
|
|
876
960
|
const pattern = param === PRIM_TYPE ? primTypeTypes(values[0]) : (PRIM_PARAM_TYPES[param] ?? []);
|
|
877
|
-
return values.map((
|
|
961
|
+
return values.map((v, i) => (GLTF_RULES.has(param) && v === '' ? 'string' : pattern[i % pattern.length]));
|
|
878
962
|
}
|
|
879
963
|
const PER_FACE_RULES = new Set([
|
|
880
964
|
PRIM_COLOR, PRIM_TEXTURE, PRIM_RENDER_MATERIAL, PRIM_FULLBRIGHT, PRIM_GLOW, PRIM_BUMP_SHINY,
|
|
@@ -921,12 +1005,12 @@ const formatG = (v) => String(Number(v.toPrecision(6)));
|
|
|
921
1005
|
* the rule can run, otherwise the error text that follows "rule #N" in the
|
|
922
1006
|
* simulator's message (e.g. " (PRIM_SIZE): arg #1 vector expected but string given").
|
|
923
1007
|
*/
|
|
924
|
-
/** GLTF override rules take "" in any slot after the face to mean "no override". */
|
|
925
|
-
const GLTF_RULES = new Set([PRIM_GLTF_BASE_COLOR, PRIM_GLTF_NORMAL, PRIM_GLTF_METALLIC_ROUGHNESS, PRIM_GLTF_EMISSIVE]);
|
|
926
1008
|
export function checkPrimRule(param, rules, cursor) {
|
|
927
1009
|
const name = RULE_NAMES.get(param);
|
|
928
|
-
if (name === undefined
|
|
1010
|
+
if (name === undefined)
|
|
929
1011
|
return ': unknown rule';
|
|
1012
|
+
if (writePrimParamSlots(param, rules, cursor) === null)
|
|
1013
|
+
return param === PRIM_TYPE ? null : ': unknown rule';
|
|
930
1014
|
const pattern = param === PRIM_TYPE ? primTypeTypes(rules[cursor]) : PRIM_PARAM_TYPES[param];
|
|
931
1015
|
const expected = PER_FACE_RULES.has(param) ? ['integer', ...pattern] : pattern;
|
|
932
1016
|
for (let i = 0; i < expected.length; i++) {
|