@daidr/minecraft-skin-renderer 0.1.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/README.md +247 -0
- package/dist/animation/AnimationController.d.mts +15 -0
- package/dist/animation/AnimationController.d.mts.map +1 -0
- package/dist/animation/AnimationController.mjs +146 -0
- package/dist/animation/AnimationController.mjs.map +1 -0
- package/dist/animation/easing.mjs +9 -0
- package/dist/animation/easing.mjs.map +1 -0
- package/dist/animation/presets/fly.mjs +176 -0
- package/dist/animation/presets/fly.mjs.map +1 -0
- package/dist/animation/presets/idle.mjs +114 -0
- package/dist/animation/presets/idle.mjs.map +1 -0
- package/dist/animation/presets/index.mjs +7 -0
- package/dist/animation/presets/run.mjs +126 -0
- package/dist/animation/presets/run.mjs.map +1 -0
- package/dist/animation/presets/utils.mjs +166 -0
- package/dist/animation/presets/utils.mjs.map +1 -0
- package/dist/animation/presets/walk.mjs +76 -0
- package/dist/animation/presets/walk.mjs.map +1 -0
- package/dist/animation/types.d.mts +50 -0
- package/dist/animation/types.d.mts.map +1 -0
- package/dist/animation/types.mjs +22 -0
- package/dist/animation/types.mjs.map +1 -0
- package/dist/core/camera/Camera.d.mts +33 -0
- package/dist/core/camera/Camera.d.mts.map +1 -0
- package/dist/core/camera/Camera.mjs +77 -0
- package/dist/core/camera/Camera.mjs.map +1 -0
- package/dist/core/camera/OrbitControls.d.mts +50 -0
- package/dist/core/camera/OrbitControls.d.mts.map +1 -0
- package/dist/core/camera/OrbitControls.mjs +170 -0
- package/dist/core/camera/OrbitControls.mjs.map +1 -0
- package/dist/core/math/index.mjs +6 -0
- package/dist/core/math/mat4.d.mts +61 -0
- package/dist/core/math/mat4.d.mts.map +1 -0
- package/dist/core/math/mat4.mjs +513 -0
- package/dist/core/math/mat4.mjs.map +1 -0
- package/dist/core/math/quat.d.mts +61 -0
- package/dist/core/math/quat.d.mts.map +1 -0
- package/dist/core/math/quat.mjs +360 -0
- package/dist/core/math/quat.mjs.map +1 -0
- package/dist/core/math/utils.d.mts +43 -0
- package/dist/core/math/utils.d.mts.map +1 -0
- package/dist/core/math/utils.mjs +85 -0
- package/dist/core/math/utils.mjs.map +1 -0
- package/dist/core/math/vec3.d.mts +61 -0
- package/dist/core/math/vec3.d.mts.map +1 -0
- package/dist/core/math/vec3.mjs +198 -0
- package/dist/core/math/vec3.mjs.map +1 -0
- package/dist/core/plugins/registry.mjs +29 -0
- package/dist/core/plugins/registry.mjs.map +1 -0
- package/dist/core/plugins/types.d.mts +34 -0
- package/dist/core/plugins/types.d.mts.map +1 -0
- package/dist/core/renderer/registry.d.mts +46 -0
- package/dist/core/renderer/registry.d.mts.map +1 -0
- package/dist/core/renderer/registry.mjs +46 -0
- package/dist/core/renderer/registry.mjs.map +1 -0
- package/dist/core/renderer/shader-composer.mjs +30 -0
- package/dist/core/renderer/shader-composer.mjs.map +1 -0
- package/dist/core/renderer/types.d.mts +172 -0
- package/dist/core/renderer/types.d.mts.map +1 -0
- package/dist/core/renderer/types.mjs +90 -0
- package/dist/core/renderer/types.mjs.map +1 -0
- package/dist/core/renderer/utils.mjs +20 -0
- package/dist/core/renderer/utils.mjs.map +1 -0
- package/dist/core/renderer/webgl/WebGLBuffer.mjs +57 -0
- package/dist/core/renderer/webgl/WebGLBuffer.mjs.map +1 -0
- package/dist/core/renderer/webgl/WebGLPipeline.mjs +259 -0
- package/dist/core/renderer/webgl/WebGLPipeline.mjs.map +1 -0
- package/dist/core/renderer/webgl/WebGLRenderer.mjs +140 -0
- package/dist/core/renderer/webgl/WebGLRenderer.mjs.map +1 -0
- package/dist/core/renderer/webgl/WebGLTexture.mjs +87 -0
- package/dist/core/renderer/webgl/WebGLTexture.mjs.map +1 -0
- package/dist/core/renderer/webgl/plugin.d.mts +8 -0
- package/dist/core/renderer/webgl/plugin.d.mts.map +1 -0
- package/dist/core/renderer/webgl/plugin.mjs +24 -0
- package/dist/core/renderer/webgl/plugin.mjs.map +1 -0
- package/dist/core/renderer/webgl/shaders/index.mjs +81 -0
- package/dist/core/renderer/webgl/shaders/index.mjs.map +1 -0
- package/dist/core/renderer/webgpu/WebGPUBuffer.mjs +52 -0
- package/dist/core/renderer/webgpu/WebGPUBuffer.mjs.map +1 -0
- package/dist/core/renderer/webgpu/WebGPUPipeline.mjs +167 -0
- package/dist/core/renderer/webgpu/WebGPUPipeline.mjs.map +1 -0
- package/dist/core/renderer/webgpu/WebGPURenderer.mjs +299 -0
- package/dist/core/renderer/webgpu/WebGPURenderer.mjs.map +1 -0
- package/dist/core/renderer/webgpu/WebGPUTexture.mjs +126 -0
- package/dist/core/renderer/webgpu/WebGPUTexture.mjs.map +1 -0
- package/dist/core/renderer/webgpu/plugin.d.mts +8 -0
- package/dist/core/renderer/webgpu/plugin.d.mts.map +1 -0
- package/dist/core/renderer/webgpu/plugin.mjs +35 -0
- package/dist/core/renderer/webgpu/plugin.mjs.map +1 -0
- package/dist/core/renderer/webgpu/shaders/index.mjs +84 -0
- package/dist/core/renderer/webgpu/shaders/index.mjs.map +1 -0
- package/dist/index.d.mts +16 -0
- package/dist/index.mjs +19 -0
- package/dist/model/PlayerModel.d.mts +8 -0
- package/dist/model/PlayerModel.d.mts.map +1 -0
- package/dist/model/PlayerModel.mjs +253 -0
- package/dist/model/PlayerModel.mjs.map +1 -0
- package/dist/model/bone-utils.mjs +3 -0
- package/dist/model/constants.mjs +20 -0
- package/dist/model/constants.mjs.map +1 -0
- package/dist/model/geometry/BoxGeometry.mjs +316 -0
- package/dist/model/geometry/BoxGeometry.mjs.map +1 -0
- package/dist/model/geometry/index.mjs +3 -0
- package/dist/model/index.mjs +10 -0
- package/dist/model/types.d.mts +64 -0
- package/dist/model/types.d.mts.map +1 -0
- package/dist/model/types.mjs +67 -0
- package/dist/model/types.mjs.map +1 -0
- package/dist/model/uv/CapeUV.mjs +25 -0
- package/dist/model/uv/CapeUV.mjs.map +1 -0
- package/dist/model/uv/SkinUV.mjs +104 -0
- package/dist/model/uv/SkinUV.mjs.map +1 -0
- package/dist/model/uv/common.mjs +147 -0
- package/dist/model/uv/common.mjs.map +1 -0
- package/dist/panorama.d.mts +2 -0
- package/dist/panorama.mjs +3 -0
- package/dist/plugins/panorama/PanoramaRenderer.mjs +94 -0
- package/dist/plugins/panorama/PanoramaRenderer.mjs.map +1 -0
- package/dist/plugins/panorama/SkyboxGeometry.mjs +132 -0
- package/dist/plugins/panorama/SkyboxGeometry.mjs.map +1 -0
- package/dist/plugins/panorama/plugin.d.mts +8 -0
- package/dist/plugins/panorama/plugin.d.mts.map +1 -0
- package/dist/plugins/panorama/plugin.mjs +13 -0
- package/dist/plugins/panorama/plugin.mjs.map +1 -0
- package/dist/plugins/panorama/shaders/webgl.mjs +59 -0
- package/dist/plugins/panorama/shaders/webgl.mjs.map +1 -0
- package/dist/plugins/panorama/shaders/webgpu.mjs +70 -0
- package/dist/plugins/panorama/shaders/webgpu.mjs.map +1 -0
- package/dist/texture/TextureLoader.d.mts +22 -0
- package/dist/texture/TextureLoader.d.mts.map +1 -0
- package/dist/texture/TextureLoader.mjs +114 -0
- package/dist/texture/TextureLoader.mjs.map +1 -0
- package/dist/viewer/BoneMatrixComputer.mjs +82 -0
- package/dist/viewer/BoneMatrixComputer.mjs.map +1 -0
- package/dist/viewer/RenderLoop.mjs +45 -0
- package/dist/viewer/RenderLoop.mjs.map +1 -0
- package/dist/viewer/RenderState.mjs +44 -0
- package/dist/viewer/RenderState.mjs.map +1 -0
- package/dist/viewer/ResourceManager.mjs +278 -0
- package/dist/viewer/ResourceManager.mjs.map +1 -0
- package/dist/viewer/SkinViewer.d.mts +98 -0
- package/dist/viewer/SkinViewer.d.mts.map +1 -0
- package/dist/viewer/SkinViewer.mjs +379 -0
- package/dist/viewer/SkinViewer.mjs.map +1 -0
- package/dist/viewer/index.mjs +7 -0
- package/dist/webgl.d.mts +2 -0
- package/dist/webgl.mjs +3 -0
- package/dist/webgpu.d.mts +2 -0
- package/dist/webgpu.mjs +3 -0
- package/package.json +75 -0
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { use } from "./core/renderer/registry.mjs";
|
|
2
|
+
import { vec3, vec3Add, vec3AddMut, vec3Clone, vec3CopyMut, vec3Cross, vec3CrossMut, vec3Distance, vec3Dot, vec3Equals, vec3Length, vec3LengthSq, vec3Lerp, vec3LerpMut, vec3Mul, vec3Negate, vec3Normalize, vec3NormalizeMut, vec3Scale, vec3ScaleMut, vec3Sub, vec3SubMut, vec3ToFloat32Array, vec3TransformMat4, vec3Zero, vec3ZeroMut } from "./core/math/vec3.mjs";
|
|
3
|
+
import { mat4Clone, mat4Copy, mat4FromRotationX, mat4FromRotationY, mat4FromRotationZ, mat4FromScaling, mat4FromTranslation, mat4FromTranslationMut, mat4GetScaling, mat4GetTranslation, mat4Identity, mat4IdentityMut, mat4Invert, mat4LookAt, mat4Multiply, mat4MultiplyMut, mat4Ortho, mat4Perspective, mat4RotateX, mat4RotateY, mat4RotateZ, mat4Scale, mat4ScaleMut, mat4Translate, mat4TranslateMut, mat4Transpose, mat4Zero } from "./core/math/mat4.mjs";
|
|
4
|
+
import { quat, quatClone, quatCopyMut, quatDot, quatEquals, quatFromAxisAngle, quatFromEuler, quatGetAxisAngle, quatIdentity, quatIdentityMut, quatInvert, quatLength, quatMultiply, quatMultiplyMut, quatNormalize, quatNormalizeMut, quatRotateVec3, quatRotateX, quatRotateY, quatRotateZ, quatSlerp, quatSlerpMut, quatToFloat32Array, quatToMat4, quatToMat4Mut } from "./core/math/quat.mjs";
|
|
5
|
+
import { EPSILON, HALF_PI, PI, TWO_PI, approxEquals, clamp, degToRad, fract, isPowerOfTwo, isZero, lerp, mapRange, nextPowerOfTwo, radToDeg, seededRandom, sign, smoothstep, wrap } from "./core/math/utils.mjs";
|
|
6
|
+
import "./core/math/index.mjs";
|
|
7
|
+
import { createCamera } from "./core/camera/Camera.mjs";
|
|
8
|
+
import { createOrbitControls } from "./core/camera/OrbitControls.mjs";
|
|
9
|
+
import { detectBestBackend, isWebGL2Supported, isWebGPUSupported } from "./core/renderer/types.mjs";
|
|
10
|
+
import { PART_NAMES, createDefaultVisibility } from "./model/types.mjs";
|
|
11
|
+
import { createPlayerSkeleton } from "./model/PlayerModel.mjs";
|
|
12
|
+
import { loadCapeTexture, loadElytraTexture, loadSkinTexture } from "./texture/TextureLoader.mjs";
|
|
13
|
+
import { getAnimation, registerAnimation } from "./animation/types.mjs";
|
|
14
|
+
import { createAnimationController, updateAnimationController } from "./animation/AnimationController.mjs";
|
|
15
|
+
import { createSkinViewer } from "./viewer/SkinViewer.mjs";
|
|
16
|
+
import "./viewer/index.mjs";
|
|
17
|
+
import "./model/index.mjs";
|
|
18
|
+
|
|
19
|
+
export { EPSILON, HALF_PI, PART_NAMES, PI, TWO_PI, approxEquals, clamp, createAnimationController, createCamera, createDefaultVisibility, createOrbitControls, createPlayerSkeleton, createSkinViewer, degToRad, detectBestBackend, fract, getAnimation, isPowerOfTwo, isWebGL2Supported, isWebGPUSupported, isZero, lerp, loadCapeTexture, loadElytraTexture, loadSkinTexture, mapRange, mat4Clone, mat4Copy, mat4FromRotationX, mat4FromRotationY, mat4FromRotationZ, mat4FromScaling, mat4FromTranslation, mat4FromTranslationMut, mat4GetScaling, mat4GetTranslation, mat4Identity, mat4IdentityMut, mat4Invert, mat4LookAt, mat4Multiply, mat4MultiplyMut, mat4Ortho, mat4Perspective, mat4RotateX, mat4RotateY, mat4RotateZ, mat4Scale, mat4ScaleMut, mat4Translate, mat4TranslateMut, mat4Transpose, mat4Zero, nextPowerOfTwo, quat, quatClone, quatCopyMut, quatDot, quatEquals, quatFromAxisAngle, quatFromEuler, quatGetAxisAngle, quatIdentity, quatIdentityMut, quatInvert, quatLength, quatMultiply, quatMultiplyMut, quatNormalize, quatNormalizeMut, quatRotateVec3, quatRotateX, quatRotateY, quatRotateZ, quatSlerp, quatSlerpMut, quatToFloat32Array, quatToMat4, quatToMat4Mut, radToDeg, registerAnimation, seededRandom, sign, smoothstep, updateAnimationController, use, vec3, vec3Add, vec3AddMut, vec3Clone, vec3CopyMut, vec3Cross, vec3CrossMut, vec3Distance, vec3Dot, vec3Equals, vec3Length, vec3LengthSq, vec3Lerp, vec3LerpMut, vec3Mul, vec3Negate, vec3Normalize, vec3NormalizeMut, vec3Scale, vec3ScaleMut, vec3Sub, vec3SubMut, vec3ToFloat32Array, vec3TransformMat4, vec3Zero, vec3ZeroMut, wrap };
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { ModelVariant, PlayerSkeleton } from "./types.mjs";
|
|
2
|
+
|
|
3
|
+
//#region src/model/PlayerModel.d.ts
|
|
4
|
+
/** Create the player skeleton */
|
|
5
|
+
declare function createPlayerSkeleton(variant?: ModelVariant): PlayerSkeleton;
|
|
6
|
+
//#endregion
|
|
7
|
+
export { createPlayerSkeleton };
|
|
8
|
+
//# sourceMappingURL=PlayerModel.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PlayerModel.d.mts","names":[],"sources":["../../src/model/PlayerModel.ts"],"mappings":";;;;iBA2DgB,oBAAA,CAAqB,OAAA,GAAS,YAAA,GAA2B,cAAA"}
|
|
@@ -0,0 +1,253 @@
|
|
|
1
|
+
import { quatFromEuler, quatIdentity } from "../core/math/quat.mjs";
|
|
2
|
+
import { degToRad } from "../core/math/utils.mjs";
|
|
3
|
+
import "../core/math/index.mjs";
|
|
4
|
+
import { BoneIndex } from "./types.mjs";
|
|
5
|
+
import { BONE_OVERLAY_SCALE } from "./constants.mjs";
|
|
6
|
+
|
|
7
|
+
//#region src/model/PlayerModel.ts
|
|
8
|
+
/**
|
|
9
|
+
* Player model skeleton definition
|
|
10
|
+
* Based on Minecraft's player model structure
|
|
11
|
+
*/
|
|
12
|
+
/**
|
|
13
|
+
* Minecraft player dimensions (in pixels, 1 pixel = 1 unit)
|
|
14
|
+
* Head: 8x8x8
|
|
15
|
+
* Body: 8x12x4
|
|
16
|
+
* Arms: 4x12x4 (classic) or 3x12x4 (slim)
|
|
17
|
+
* Legs: 4x12x4
|
|
18
|
+
*/
|
|
19
|
+
/** Create a bone definition */
|
|
20
|
+
function createBone(index, name, parentIndex, position, pivot, size) {
|
|
21
|
+
return {
|
|
22
|
+
index,
|
|
23
|
+
name,
|
|
24
|
+
parentIndex,
|
|
25
|
+
position,
|
|
26
|
+
pivot,
|
|
27
|
+
rotation: quatIdentity(),
|
|
28
|
+
positionOffset: [
|
|
29
|
+
0,
|
|
30
|
+
0,
|
|
31
|
+
0
|
|
32
|
+
],
|
|
33
|
+
size
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
/** Create an overlay bone that follows a parent bone with inflated size */
|
|
37
|
+
function createOverlayBone(index, name, parentIndex, parentSize, scale = BONE_OVERLAY_SCALE) {
|
|
38
|
+
return createBone(index, name, parentIndex, [
|
|
39
|
+
0,
|
|
40
|
+
0,
|
|
41
|
+
0
|
|
42
|
+
], [
|
|
43
|
+
0,
|
|
44
|
+
0,
|
|
45
|
+
0
|
|
46
|
+
], [
|
|
47
|
+
parentSize[0] + scale * 2,
|
|
48
|
+
parentSize[1] + scale * 2,
|
|
49
|
+
parentSize[2] + scale * 2
|
|
50
|
+
]);
|
|
51
|
+
}
|
|
52
|
+
/** Create the player skeleton */
|
|
53
|
+
function createPlayerSkeleton(variant = "classic") {
|
|
54
|
+
const armWidth = variant === "slim" ? 3 : 4;
|
|
55
|
+
const bones = /* @__PURE__ */ new Map();
|
|
56
|
+
bones.set(BoneIndex.Root, createBone(BoneIndex.Root, "root", null, [
|
|
57
|
+
0,
|
|
58
|
+
0,
|
|
59
|
+
0
|
|
60
|
+
], [
|
|
61
|
+
0,
|
|
62
|
+
0,
|
|
63
|
+
0
|
|
64
|
+
], [
|
|
65
|
+
0,
|
|
66
|
+
0,
|
|
67
|
+
0
|
|
68
|
+
]));
|
|
69
|
+
bones.set(BoneIndex.Body, createBone(BoneIndex.Body, "body", BoneIndex.Root, [
|
|
70
|
+
0,
|
|
71
|
+
24,
|
|
72
|
+
0
|
|
73
|
+
], [
|
|
74
|
+
0,
|
|
75
|
+
0,
|
|
76
|
+
0
|
|
77
|
+
], [
|
|
78
|
+
8,
|
|
79
|
+
12,
|
|
80
|
+
4
|
|
81
|
+
]));
|
|
82
|
+
bones.set(BoneIndex.Head, createBone(BoneIndex.Head, "head", BoneIndex.Body, [
|
|
83
|
+
0,
|
|
84
|
+
0,
|
|
85
|
+
0
|
|
86
|
+
], [
|
|
87
|
+
0,
|
|
88
|
+
0,
|
|
89
|
+
0
|
|
90
|
+
], [
|
|
91
|
+
8,
|
|
92
|
+
8,
|
|
93
|
+
8
|
|
94
|
+
]));
|
|
95
|
+
bones.set(BoneIndex.RightArm, createBone(BoneIndex.RightArm, "rightArm", BoneIndex.Body, [
|
|
96
|
+
-(4 + armWidth / 2),
|
|
97
|
+
0,
|
|
98
|
+
0
|
|
99
|
+
], [
|
|
100
|
+
0,
|
|
101
|
+
0,
|
|
102
|
+
0
|
|
103
|
+
], [
|
|
104
|
+
armWidth,
|
|
105
|
+
12,
|
|
106
|
+
4
|
|
107
|
+
]));
|
|
108
|
+
bones.set(BoneIndex.LeftArm, createBone(BoneIndex.LeftArm, "leftArm", BoneIndex.Body, [
|
|
109
|
+
4 + armWidth / 2,
|
|
110
|
+
0,
|
|
111
|
+
0
|
|
112
|
+
], [
|
|
113
|
+
0,
|
|
114
|
+
0,
|
|
115
|
+
0
|
|
116
|
+
], [
|
|
117
|
+
armWidth,
|
|
118
|
+
12,
|
|
119
|
+
4
|
|
120
|
+
]));
|
|
121
|
+
bones.set(BoneIndex.RightLeg, createBone(BoneIndex.RightLeg, "rightLeg", BoneIndex.Body, [
|
|
122
|
+
-2,
|
|
123
|
+
-12,
|
|
124
|
+
0
|
|
125
|
+
], [
|
|
126
|
+
0,
|
|
127
|
+
0,
|
|
128
|
+
0
|
|
129
|
+
], [
|
|
130
|
+
4,
|
|
131
|
+
12,
|
|
132
|
+
4
|
|
133
|
+
]));
|
|
134
|
+
bones.set(BoneIndex.LeftLeg, createBone(BoneIndex.LeftLeg, "leftLeg", BoneIndex.Body, [
|
|
135
|
+
2,
|
|
136
|
+
-12,
|
|
137
|
+
0
|
|
138
|
+
], [
|
|
139
|
+
0,
|
|
140
|
+
0,
|
|
141
|
+
0
|
|
142
|
+
], [
|
|
143
|
+
4,
|
|
144
|
+
12,
|
|
145
|
+
4
|
|
146
|
+
]));
|
|
147
|
+
bones.set(BoneIndex.HeadOverlay, createOverlayBone(BoneIndex.HeadOverlay, "headOverlay", BoneIndex.Head, [
|
|
148
|
+
8,
|
|
149
|
+
8,
|
|
150
|
+
8
|
|
151
|
+
]));
|
|
152
|
+
bones.set(BoneIndex.BodyOverlay, createOverlayBone(BoneIndex.BodyOverlay, "bodyOverlay", BoneIndex.Body, [
|
|
153
|
+
8,
|
|
154
|
+
12,
|
|
155
|
+
4
|
|
156
|
+
]));
|
|
157
|
+
bones.set(BoneIndex.RightArmOverlay, createOverlayBone(BoneIndex.RightArmOverlay, "rightArmOverlay", BoneIndex.RightArm, [
|
|
158
|
+
armWidth,
|
|
159
|
+
12,
|
|
160
|
+
4
|
|
161
|
+
]));
|
|
162
|
+
bones.set(BoneIndex.LeftArmOverlay, createOverlayBone(BoneIndex.LeftArmOverlay, "leftArmOverlay", BoneIndex.LeftArm, [
|
|
163
|
+
armWidth,
|
|
164
|
+
12,
|
|
165
|
+
4
|
|
166
|
+
]));
|
|
167
|
+
bones.set(BoneIndex.RightLegOverlay, createOverlayBone(BoneIndex.RightLegOverlay, "rightLegOverlay", BoneIndex.RightLeg, [
|
|
168
|
+
4,
|
|
169
|
+
12,
|
|
170
|
+
4
|
|
171
|
+
]));
|
|
172
|
+
bones.set(BoneIndex.LeftLegOverlay, createOverlayBone(BoneIndex.LeftLegOverlay, "leftLegOverlay", BoneIndex.LeftLeg, [
|
|
173
|
+
4,
|
|
174
|
+
12,
|
|
175
|
+
4
|
|
176
|
+
]));
|
|
177
|
+
bones.set(BoneIndex.Cape, createBone(BoneIndex.Cape, "cape", BoneIndex.Body, [
|
|
178
|
+
0,
|
|
179
|
+
0,
|
|
180
|
+
-2
|
|
181
|
+
], [
|
|
182
|
+
0,
|
|
183
|
+
0,
|
|
184
|
+
0
|
|
185
|
+
], [
|
|
186
|
+
10,
|
|
187
|
+
16,
|
|
188
|
+
1
|
|
189
|
+
]));
|
|
190
|
+
bones.set(BoneIndex.LeftWing, createBone(BoneIndex.LeftWing, "leftWing", BoneIndex.Body, [
|
|
191
|
+
5,
|
|
192
|
+
-1,
|
|
193
|
+
-2
|
|
194
|
+
], [
|
|
195
|
+
0,
|
|
196
|
+
0,
|
|
197
|
+
0
|
|
198
|
+
], [
|
|
199
|
+
10,
|
|
200
|
+
20,
|
|
201
|
+
2
|
|
202
|
+
]));
|
|
203
|
+
bones.set(BoneIndex.RightWing, createBone(BoneIndex.RightWing, "rightWing", BoneIndex.Body, [
|
|
204
|
+
-5,
|
|
205
|
+
-1,
|
|
206
|
+
-2
|
|
207
|
+
], [
|
|
208
|
+
0,
|
|
209
|
+
0,
|
|
210
|
+
0
|
|
211
|
+
], [
|
|
212
|
+
10,
|
|
213
|
+
20,
|
|
214
|
+
2
|
|
215
|
+
]));
|
|
216
|
+
const leftWing = bones.get(BoneIndex.LeftWing);
|
|
217
|
+
const rightWing = bones.get(BoneIndex.RightWing);
|
|
218
|
+
leftWing.rotation = quatFromEuler(degToRad(15), degToRad(.5), degToRad(15));
|
|
219
|
+
rightWing.rotation = quatFromEuler(degToRad(15), degToRad(-.5), degToRad(-15));
|
|
220
|
+
return {
|
|
221
|
+
variant,
|
|
222
|
+
bones
|
|
223
|
+
};
|
|
224
|
+
}
|
|
225
|
+
/** Set bone rotation */
|
|
226
|
+
function setBoneRotation(skeleton, boneIndex, rotation) {
|
|
227
|
+
const bone = skeleton.bones.get(boneIndex);
|
|
228
|
+
if (bone) bone.rotation = rotation;
|
|
229
|
+
}
|
|
230
|
+
/** Set bone position offset (for animation) */
|
|
231
|
+
function setBonePositionOffset(skeleton, boneIndex, offset) {
|
|
232
|
+
const bone = skeleton.bones.get(boneIndex);
|
|
233
|
+
if (bone) bone.positionOffset = offset;
|
|
234
|
+
}
|
|
235
|
+
/** Reset all bone rotations and position offsets */
|
|
236
|
+
function resetSkeleton(skeleton) {
|
|
237
|
+
for (const bone of skeleton.bones.values()) {
|
|
238
|
+
bone.rotation = quatIdentity();
|
|
239
|
+
bone.positionOffset = [
|
|
240
|
+
0,
|
|
241
|
+
0,
|
|
242
|
+
0
|
|
243
|
+
];
|
|
244
|
+
}
|
|
245
|
+
const leftWing = skeleton.bones.get(BoneIndex.LeftWing);
|
|
246
|
+
const rightWing = skeleton.bones.get(BoneIndex.RightWing);
|
|
247
|
+
if (leftWing) leftWing.rotation = quatFromEuler(degToRad(15), degToRad(.5), degToRad(15));
|
|
248
|
+
if (rightWing) rightWing.rotation = quatFromEuler(degToRad(15), degToRad(-.5), degToRad(-15));
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
//#endregion
|
|
252
|
+
export { createPlayerSkeleton, resetSkeleton, setBonePositionOffset, setBoneRotation };
|
|
253
|
+
//# sourceMappingURL=PlayerModel.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PlayerModel.mjs","names":[],"sources":["../../src/model/PlayerModel.ts"],"sourcesContent":["/**\n * Player model skeleton definition\n * Based on Minecraft's player model structure\n */\n\nimport { quatIdentity, quatFromEuler, degToRad } from \"../core/math\";\nimport type { Quat, Vec3 } from \"../core/math\";\nimport { BoneIndex } from \"./types\";\nimport type { Bone, ModelVariant, PlayerSkeleton } from \"./types\";\nimport { BONE_OVERLAY_SCALE } from \"./constants\";\n\n/**\n * Minecraft player dimensions (in pixels, 1 pixel = 1 unit)\n * Head: 8x8x8\n * Body: 8x12x4\n * Arms: 4x12x4 (classic) or 3x12x4 (slim)\n * Legs: 4x12x4\n */\n\n/** Create a bone definition */\nfunction createBone(\n index: BoneIndex,\n name: string,\n parentIndex: BoneIndex | null,\n position: Vec3,\n pivot: Vec3,\n size: Vec3,\n): Bone {\n return {\n index,\n name,\n parentIndex,\n position,\n pivot,\n rotation: quatIdentity(),\n positionOffset: [0, 0, 0],\n size,\n };\n}\n\n/** Create an overlay bone that follows a parent bone with inflated size */\nfunction createOverlayBone(\n index: BoneIndex,\n name: string,\n parentIndex: BoneIndex,\n parentSize: Vec3,\n scale = BONE_OVERLAY_SCALE,\n): Bone {\n return createBone(\n index,\n name,\n parentIndex,\n [0, 0, 0],\n [0, 0, 0],\n [parentSize[0] + scale * 2, parentSize[1] + scale * 2, parentSize[2] + scale * 2],\n );\n}\n\n/** Create the player skeleton */\nexport function createPlayerSkeleton(variant: ModelVariant = \"classic\"): PlayerSkeleton {\n const armWidth = variant === \"slim\" ? 3 : 4;\n const bones = new Map<BoneIndex, Bone>();\n\n // Minecraft player model coordinates (Y up, origin at feet):\n // - Legs: y = 0 to 12\n // - Body: y = 12 to 24\n // - Head: y = 24 to 32\n // - Arms: y = 12 to 24 (attached at shoulders, y = 22)\n\n // Root bone (at feet level, center)\n bones.set(\n BoneIndex.Root,\n createBone(BoneIndex.Root, \"root\", null, [0, 0, 0], [0, 0, 0], [0, 0, 0]),\n );\n\n // Body (pivot at bottom of body, y=12)\n bones.set(\n BoneIndex.Body,\n createBone(\n BoneIndex.Body,\n \"body\",\n BoneIndex.Root,\n [0, 24, 0], // Position body top at y=24\n [0, 0, 0], // Pivot at body top (for head attachment)\n [8, 12, 4], // Body size\n ),\n );\n\n // Head (attached to body top, y=24)\n bones.set(\n BoneIndex.Head,\n createBone(\n BoneIndex.Head,\n \"head\",\n BoneIndex.Body,\n [0, 0, 0], // At body top\n [0, 0, 0], // Pivot at neck (head bottom)\n [8, 8, 8], // Head size\n ),\n );\n\n // Right Arm (attached at shoulder, x = -5 or -5.5 for slim)\n bones.set(\n BoneIndex.RightArm,\n createBone(\n BoneIndex.RightArm,\n \"rightArm\",\n BoneIndex.Body,\n [-(4 + armWidth / 2), 0, 0], // Shoulder position (at body top)\n [0, 0, 0], // Pivot at shoulder (arm top)\n [armWidth, 12, 4], // Arm size\n ),\n );\n\n // Left Arm (attached at shoulder)\n bones.set(\n BoneIndex.LeftArm,\n createBone(\n BoneIndex.LeftArm,\n \"leftArm\",\n BoneIndex.Body,\n [4 + armWidth / 2, 0, 0], // Shoulder position (at body top)\n [0, 0, 0], // Pivot at shoulder\n [armWidth, 12, 4], // Arm size\n ),\n );\n\n // Right Leg (attached to body at hip level)\n bones.set(\n BoneIndex.RightLeg,\n createBone(\n BoneIndex.RightLeg,\n \"rightLeg\",\n BoneIndex.Body,\n [-2, -12, 0], // Hip position (relative to body top at y=24, so y=24-12=12)\n [0, 0, 0], // Pivot at hip (leg top)\n [4, 12, 4], // Leg size\n ),\n );\n\n // Left Leg (attached to body at hip level)\n bones.set(\n BoneIndex.LeftLeg,\n createBone(\n BoneIndex.LeftLeg,\n \"leftLeg\",\n BoneIndex.Body,\n [2, -12, 0], // Hip position (relative to body top)\n [0, 0, 0], // Pivot at hip\n [4, 12, 4], // Leg size\n ),\n );\n\n // Overlay layers (slightly larger, same pivot)\n bones.set(\n BoneIndex.HeadOverlay,\n createOverlayBone(BoneIndex.HeadOverlay, \"headOverlay\", BoneIndex.Head, [8, 8, 8]),\n );\n bones.set(\n BoneIndex.BodyOverlay,\n createOverlayBone(BoneIndex.BodyOverlay, \"bodyOverlay\", BoneIndex.Body, [8, 12, 4]),\n );\n bones.set(\n BoneIndex.RightArmOverlay,\n createOverlayBone(BoneIndex.RightArmOverlay, \"rightArmOverlay\", BoneIndex.RightArm, [\n armWidth,\n 12,\n 4,\n ]),\n );\n bones.set(\n BoneIndex.LeftArmOverlay,\n createOverlayBone(BoneIndex.LeftArmOverlay, \"leftArmOverlay\", BoneIndex.LeftArm, [\n armWidth,\n 12,\n 4,\n ]),\n );\n bones.set(\n BoneIndex.RightLegOverlay,\n createOverlayBone(BoneIndex.RightLegOverlay, \"rightLegOverlay\", BoneIndex.RightLeg, [4, 12, 4]),\n );\n bones.set(\n BoneIndex.LeftLegOverlay,\n createOverlayBone(BoneIndex.LeftLegOverlay, \"leftLegOverlay\", BoneIndex.LeftLeg, [4, 12, 4]),\n );\n\n // Cape (attached to body back)\n // Cape hangs from the neck, pivot at the top attachment point\n // Body back face is at z = -2 (body is 4 deep, centered at z=0)\n // Cape should be flush against body back\n bones.set(\n BoneIndex.Cape,\n createBone(\n BoneIndex.Cape,\n \"cape\",\n BoneIndex.Body,\n [0, 0, -2], // At body back surface (z = -2)\n [0, 0, 0], // Pivot at bone origin (top of cape attachment)\n [10, 16, 1], // Cape size: 10 wide, 16 tall, 1 deep\n ),\n );\n\n // Elytra wings (attached to body back at the spine)\n // Based on skinview3d: wings pivot from attachment point at spine\n // Left wing pivot is 5 units to the left of center, extends outward\n // Wing rotates around this pivot point for open/close animations\n // Y=-2 to position wings slightly below shoulders (body top is at y=0)\n bones.set(\n BoneIndex.LeftWing,\n createBone(\n BoneIndex.LeftWing,\n \"leftWing\",\n BoneIndex.Body,\n [5, -1, -2], // Pivot point: below shoulders, at body back\n [0, 0, 0], // Pivot at bone origin\n [10, 20, 2], // Wing size for UV mapping\n ),\n );\n\n bones.set(\n BoneIndex.RightWing,\n createBone(\n BoneIndex.RightWing,\n \"rightWing\",\n BoneIndex.Body,\n [-5, -1, -2], // Pivot point: below shoulders, at body back (mirrored)\n [0, 0, 0], // Pivot at bone origin (mirrored)\n [10, 20, 2], // Wing size for UV mapping\n ),\n );\n\n // Set default elytra rotation to match idle animation's closed position\n const leftWing = bones.get(BoneIndex.LeftWing)!;\n const rightWing = bones.get(BoneIndex.RightWing)!;\n leftWing.rotation = quatFromEuler(degToRad(15), degToRad(0.5), degToRad(15));\n rightWing.rotation = quatFromEuler(degToRad(15), degToRad(-0.5), degToRad(-15));\n\n return { variant, bones };\n}\n\n/** Set bone rotation */\nexport function setBoneRotation(\n skeleton: PlayerSkeleton,\n boneIndex: BoneIndex,\n rotation: Quat,\n): void {\n const bone = skeleton.bones.get(boneIndex);\n if (bone) {\n bone.rotation = rotation;\n }\n}\n\n/** Set bone position offset (for animation) */\nexport function setBonePositionOffset(\n skeleton: PlayerSkeleton,\n boneIndex: BoneIndex,\n offset: Vec3,\n): void {\n const bone = skeleton.bones.get(boneIndex);\n if (bone) {\n bone.positionOffset = offset;\n }\n}\n\n/** Reset all bone rotations and position offsets */\nexport function resetSkeleton(skeleton: PlayerSkeleton): void {\n for (const bone of skeleton.bones.values()) {\n bone.rotation = quatIdentity();\n bone.positionOffset = [0, 0, 0];\n }\n\n // Restore default elytra rotation (idle closed position)\n const leftWing = skeleton.bones.get(BoneIndex.LeftWing);\n const rightWing = skeleton.bones.get(BoneIndex.RightWing);\n if (leftWing) {\n leftWing.rotation = quatFromEuler(degToRad(15), degToRad(0.5), degToRad(15));\n }\n if (rightWing) {\n rightWing.rotation = quatFromEuler(degToRad(15), degToRad(-0.5), degToRad(-15));\n }\n}\n\n/** Clone a skeleton */\nexport function cloneSkeleton(skeleton: PlayerSkeleton): PlayerSkeleton {\n const bones = new Map<BoneIndex, Bone>();\n for (const [index, bone] of skeleton.bones) {\n bones.set(index, {\n ...bone,\n position: [...bone.position] as Vec3,\n pivot: [...bone.pivot] as Vec3,\n rotation: [...bone.rotation] as Quat,\n positionOffset: [...bone.positionOffset] as Vec3,\n size: [...bone.size] as Vec3,\n });\n }\n return { variant: skeleton.variant, bones };\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
//#region src/model/constants.ts
|
|
2
|
+
/**
|
|
3
|
+
* Model constants
|
|
4
|
+
*
|
|
5
|
+
* Centralized constants for texture dimensions, UV processing, and geometry generation.
|
|
6
|
+
*/
|
|
7
|
+
/** Skin texture dimensions (64x64 format) */
|
|
8
|
+
const SKIN_TEXTURE_WIDTH = 64;
|
|
9
|
+
const SKIN_TEXTURE_HEIGHT = 64;
|
|
10
|
+
/** Cape texture dimensions (64x32 format) */
|
|
11
|
+
const CAPE_TEXTURE_WIDTH = 64;
|
|
12
|
+
const CAPE_TEXTURE_HEIGHT = 32;
|
|
13
|
+
/** UV inset to prevent texture edge bleeding */
|
|
14
|
+
const UV_EDGE_INSET = .001;
|
|
15
|
+
/** Bone overlay scale factor */
|
|
16
|
+
const BONE_OVERLAY_SCALE = .5;
|
|
17
|
+
|
|
18
|
+
//#endregion
|
|
19
|
+
export { BONE_OVERLAY_SCALE, CAPE_TEXTURE_HEIGHT, CAPE_TEXTURE_WIDTH, SKIN_TEXTURE_HEIGHT, SKIN_TEXTURE_WIDTH, UV_EDGE_INSET };
|
|
20
|
+
//# sourceMappingURL=constants.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"constants.mjs","names":[],"sources":["../../src/model/constants.ts"],"sourcesContent":["/**\n * Model constants\n *\n * Centralized constants for texture dimensions, UV processing, and geometry generation.\n */\n\n/** Skin texture dimensions (64x64 format) */\nexport const SKIN_TEXTURE_WIDTH = 64;\nexport const SKIN_TEXTURE_HEIGHT = 64;\n\n/** Cape texture dimensions (64x32 format) */\nexport const CAPE_TEXTURE_WIDTH = 64;\nexport const CAPE_TEXTURE_HEIGHT = 32;\n\n/** UV inset to prevent texture edge bleeding */\nexport const UV_EDGE_INSET = 0.001;\n\n/** Bone overlay scale factor */\nexport const BONE_OVERLAY_SCALE = 0.5;\n\n/** Arm width for different model variants */\nexport const ARM_WIDTH = {\n CLASSIC: 4,\n SLIM: 3,\n} as const;\n"],"mappings":";;;;;;;AAOA,MAAa,qBAAqB;AAClC,MAAa,sBAAsB;;AAGnC,MAAa,qBAAqB;AAClC,MAAa,sBAAsB;;AAGnC,MAAa,gBAAgB;;AAG7B,MAAa,qBAAqB"}
|
|
@@ -0,0 +1,316 @@
|
|
|
1
|
+
import { VERTEX_STRIDE } from "../types.mjs";
|
|
2
|
+
import { CAPE_TEXTURE_HEIGHT, CAPE_TEXTURE_WIDTH, SKIN_TEXTURE_HEIGHT, SKIN_TEXTURE_WIDTH, UV_EDGE_INSET } from "../constants.mjs";
|
|
3
|
+
|
|
4
|
+
//#region src/model/geometry/BoxGeometry.ts
|
|
5
|
+
/** Face indices for a cube */
|
|
6
|
+
var Face = /* @__PURE__ */ function(Face) {
|
|
7
|
+
Face[Face["Front"] = 0] = "Front";
|
|
8
|
+
Face[Face["Back"] = 1] = "Back";
|
|
9
|
+
Face[Face["Left"] = 2] = "Left";
|
|
10
|
+
Face[Face["Right"] = 3] = "Right";
|
|
11
|
+
Face[Face["Top"] = 4] = "Top";
|
|
12
|
+
Face[Face["Bottom"] = 5] = "Bottom";
|
|
13
|
+
return Face;
|
|
14
|
+
}(Face || {});
|
|
15
|
+
/** Normal vectors for each face */
|
|
16
|
+
const FACE_NORMALS = [
|
|
17
|
+
[
|
|
18
|
+
0,
|
|
19
|
+
0,
|
|
20
|
+
1
|
|
21
|
+
],
|
|
22
|
+
[
|
|
23
|
+
0,
|
|
24
|
+
0,
|
|
25
|
+
-1
|
|
26
|
+
],
|
|
27
|
+
[
|
|
28
|
+
-1,
|
|
29
|
+
0,
|
|
30
|
+
0
|
|
31
|
+
],
|
|
32
|
+
[
|
|
33
|
+
1,
|
|
34
|
+
0,
|
|
35
|
+
0
|
|
36
|
+
],
|
|
37
|
+
[
|
|
38
|
+
0,
|
|
39
|
+
1,
|
|
40
|
+
0
|
|
41
|
+
],
|
|
42
|
+
[
|
|
43
|
+
0,
|
|
44
|
+
-1,
|
|
45
|
+
0
|
|
46
|
+
]
|
|
47
|
+
];
|
|
48
|
+
/** UV inset constant (imported from constants) */
|
|
49
|
+
const UV_INSET = UV_EDGE_INSET;
|
|
50
|
+
/**
|
|
51
|
+
* Core function for creating box geometry with various options
|
|
52
|
+
*/
|
|
53
|
+
function createBoxGeometryCore(size, uv, boneIndex, offset, options) {
|
|
54
|
+
const { inflate = 0, mirrorX = false, textureWidth = 64, textureHeight = 64, capeUVMode = false } = options;
|
|
55
|
+
const hw = size[0] / 2 + inflate;
|
|
56
|
+
const hh = size[1] / 2 + inflate;
|
|
57
|
+
const hd = size[2] / 2 + inflate;
|
|
58
|
+
const ox = offset[0];
|
|
59
|
+
const oy = offset[1];
|
|
60
|
+
const oz = offset[2];
|
|
61
|
+
const vertexCount = 24;
|
|
62
|
+
const indexCount = 36;
|
|
63
|
+
const vertices = new Float32Array(vertexCount * VERTEX_STRIDE);
|
|
64
|
+
const indices = new Uint16Array(indexCount);
|
|
65
|
+
let vertexOffset = 0;
|
|
66
|
+
let indexOffset = 0;
|
|
67
|
+
let baseVertex = 0;
|
|
68
|
+
const mx = mirrorX ? -1 : 1;
|
|
69
|
+
const addVertex = (x, y, z, u, v, nx, ny, nz) => {
|
|
70
|
+
vertices[vertexOffset++] = x * mx;
|
|
71
|
+
vertices[vertexOffset++] = y;
|
|
72
|
+
vertices[vertexOffset++] = z;
|
|
73
|
+
vertices[vertexOffset++] = u;
|
|
74
|
+
vertices[vertexOffset++] = v;
|
|
75
|
+
vertices[vertexOffset++] = nx * mx;
|
|
76
|
+
vertices[vertexOffset++] = ny;
|
|
77
|
+
vertices[vertexOffset++] = nz;
|
|
78
|
+
vertices[vertexOffset++] = boneIndex;
|
|
79
|
+
vertices[vertexOffset++] = 0;
|
|
80
|
+
};
|
|
81
|
+
const addFaceIndices = () => {
|
|
82
|
+
if (mirrorX) {
|
|
83
|
+
indices[indexOffset++] = baseVertex + 2;
|
|
84
|
+
indices[indexOffset++] = baseVertex + 1;
|
|
85
|
+
indices[indexOffset++] = baseVertex;
|
|
86
|
+
indices[indexOffset++] = baseVertex;
|
|
87
|
+
indices[indexOffset++] = baseVertex + 3;
|
|
88
|
+
indices[indexOffset++] = baseVertex + 2;
|
|
89
|
+
} else {
|
|
90
|
+
indices[indexOffset++] = baseVertex;
|
|
91
|
+
indices[indexOffset++] = baseVertex + 1;
|
|
92
|
+
indices[indexOffset++] = baseVertex + 2;
|
|
93
|
+
indices[indexOffset++] = baseVertex + 2;
|
|
94
|
+
indices[indexOffset++] = baseVertex + 3;
|
|
95
|
+
indices[indexOffset++] = baseVertex;
|
|
96
|
+
}
|
|
97
|
+
baseVertex += 4;
|
|
98
|
+
};
|
|
99
|
+
const normalizeUV = (faceUV) => {
|
|
100
|
+
let u1 = faceUV.u1 / textureWidth;
|
|
101
|
+
let u2 = faceUV.u2 / textureWidth;
|
|
102
|
+
let v1 = faceUV.v1 / textureHeight;
|
|
103
|
+
let v2 = faceUV.v2 / textureHeight;
|
|
104
|
+
if (u1 < u2) {
|
|
105
|
+
u1 += UV_INSET;
|
|
106
|
+
u2 -= UV_INSET;
|
|
107
|
+
} else {
|
|
108
|
+
u1 -= UV_INSET;
|
|
109
|
+
u2 += UV_INSET;
|
|
110
|
+
}
|
|
111
|
+
if (v1 < v2) {
|
|
112
|
+
v1 += UV_INSET;
|
|
113
|
+
v2 -= UV_INSET;
|
|
114
|
+
} else {
|
|
115
|
+
v1 -= UV_INSET;
|
|
116
|
+
v2 += UV_INSET;
|
|
117
|
+
}
|
|
118
|
+
return [
|
|
119
|
+
u1,
|
|
120
|
+
v1,
|
|
121
|
+
u2,
|
|
122
|
+
v2
|
|
123
|
+
];
|
|
124
|
+
};
|
|
125
|
+
if (capeUVMode) {
|
|
126
|
+
{
|
|
127
|
+
const [u1, v1, u2, v2] = normalizeUV(uv.front);
|
|
128
|
+
const [nx, ny, nz] = FACE_NORMALS[Face.Front];
|
|
129
|
+
addVertex(ox - hw, oy - hh, oz + hd, u2, v2, nx, ny, nz);
|
|
130
|
+
addVertex(ox + hw, oy - hh, oz + hd, u1, v2, nx, ny, nz);
|
|
131
|
+
addVertex(ox + hw, oy + hh, oz + hd, u1, v1, nx, ny, nz);
|
|
132
|
+
addVertex(ox - hw, oy + hh, oz + hd, u2, v1, nx, ny, nz);
|
|
133
|
+
addFaceIndices();
|
|
134
|
+
}
|
|
135
|
+
{
|
|
136
|
+
const [u1, v1, u2, v2] = normalizeUV(uv.back);
|
|
137
|
+
const [nx, ny, nz] = FACE_NORMALS[Face.Back];
|
|
138
|
+
addVertex(ox + hw, oy - hh, oz - hd, u2, v2, nx, ny, nz);
|
|
139
|
+
addVertex(ox - hw, oy - hh, oz - hd, u1, v2, nx, ny, nz);
|
|
140
|
+
addVertex(ox - hw, oy + hh, oz - hd, u1, v1, nx, ny, nz);
|
|
141
|
+
addVertex(ox + hw, oy + hh, oz - hd, u2, v1, nx, ny, nz);
|
|
142
|
+
addFaceIndices();
|
|
143
|
+
}
|
|
144
|
+
{
|
|
145
|
+
const [u1, v1, u2, v2] = normalizeUV(uv.left);
|
|
146
|
+
const [nx, ny, nz] = FACE_NORMALS[Face.Left];
|
|
147
|
+
addVertex(ox - hw, oy - hh, oz - hd, u2, v2, nx, ny, nz);
|
|
148
|
+
addVertex(ox - hw, oy - hh, oz + hd, u1, v2, nx, ny, nz);
|
|
149
|
+
addVertex(ox - hw, oy + hh, oz + hd, u1, v1, nx, ny, nz);
|
|
150
|
+
addVertex(ox - hw, oy + hh, oz - hd, u2, v1, nx, ny, nz);
|
|
151
|
+
addFaceIndices();
|
|
152
|
+
}
|
|
153
|
+
{
|
|
154
|
+
const [u1, v1, u2, v2] = normalizeUV(uv.right);
|
|
155
|
+
const [nx, ny, nz] = FACE_NORMALS[Face.Right];
|
|
156
|
+
addVertex(ox + hw, oy - hh, oz + hd, u2, v2, nx, ny, nz);
|
|
157
|
+
addVertex(ox + hw, oy - hh, oz - hd, u1, v2, nx, ny, nz);
|
|
158
|
+
addVertex(ox + hw, oy + hh, oz - hd, u1, v1, nx, ny, nz);
|
|
159
|
+
addVertex(ox + hw, oy + hh, oz + hd, u2, v1, nx, ny, nz);
|
|
160
|
+
addFaceIndices();
|
|
161
|
+
}
|
|
162
|
+
{
|
|
163
|
+
const [u1, v1, u2, v2] = normalizeUV(uv.top);
|
|
164
|
+
const [nx, ny, nz] = FACE_NORMALS[Face.Top];
|
|
165
|
+
addVertex(ox - hw, oy + hh, oz + hd, u1, v2, nx, ny, nz);
|
|
166
|
+
addVertex(ox + hw, oy + hh, oz + hd, u2, v2, nx, ny, nz);
|
|
167
|
+
addVertex(ox + hw, oy + hh, oz - hd, u2, v1, nx, ny, nz);
|
|
168
|
+
addVertex(ox - hw, oy + hh, oz - hd, u1, v1, nx, ny, nz);
|
|
169
|
+
addFaceIndices();
|
|
170
|
+
}
|
|
171
|
+
{
|
|
172
|
+
const [u1, v1, u2, v2] = normalizeUV(uv.bottom);
|
|
173
|
+
const [nx, ny, nz] = FACE_NORMALS[Face.Bottom];
|
|
174
|
+
addVertex(ox - hw, oy - hh, oz - hd, u1, v1, nx, ny, nz);
|
|
175
|
+
addVertex(ox + hw, oy - hh, oz - hd, u2, v1, nx, ny, nz);
|
|
176
|
+
addVertex(ox + hw, oy - hh, oz + hd, u2, v2, nx, ny, nz);
|
|
177
|
+
addVertex(ox - hw, oy - hh, oz + hd, u1, v2, nx, ny, nz);
|
|
178
|
+
addFaceIndices();
|
|
179
|
+
}
|
|
180
|
+
} else {
|
|
181
|
+
{
|
|
182
|
+
const [u1, v1, u2, v2] = normalizeUV(uv.front);
|
|
183
|
+
const [nx, ny, nz] = FACE_NORMALS[Face.Front];
|
|
184
|
+
addVertex(ox - hw, oy - hh, oz + hd, u1, v2, nx, ny, nz);
|
|
185
|
+
addVertex(ox + hw, oy - hh, oz + hd, u2, v2, nx, ny, nz);
|
|
186
|
+
addVertex(ox + hw, oy + hh, oz + hd, u2, v1, nx, ny, nz);
|
|
187
|
+
addVertex(ox - hw, oy + hh, oz + hd, u1, v1, nx, ny, nz);
|
|
188
|
+
addFaceIndices();
|
|
189
|
+
}
|
|
190
|
+
{
|
|
191
|
+
const [u1, v1, u2, v2] = normalizeUV(uv.back);
|
|
192
|
+
const [nx, ny, nz] = FACE_NORMALS[Face.Back];
|
|
193
|
+
addVertex(ox + hw, oy - hh, oz - hd, u1, v2, nx, ny, nz);
|
|
194
|
+
addVertex(ox - hw, oy - hh, oz - hd, u2, v2, nx, ny, nz);
|
|
195
|
+
addVertex(ox - hw, oy + hh, oz - hd, u2, v1, nx, ny, nz);
|
|
196
|
+
addVertex(ox + hw, oy + hh, oz - hd, u1, v1, nx, ny, nz);
|
|
197
|
+
addFaceIndices();
|
|
198
|
+
}
|
|
199
|
+
{
|
|
200
|
+
const [u1, v1, u2, v2] = normalizeUV(uv.right);
|
|
201
|
+
const [nx, ny, nz] = FACE_NORMALS[Face.Left];
|
|
202
|
+
addVertex(ox - hw, oy - hh, oz - hd, u1, v2, nx, ny, nz);
|
|
203
|
+
addVertex(ox - hw, oy - hh, oz + hd, u2, v2, nx, ny, nz);
|
|
204
|
+
addVertex(ox - hw, oy + hh, oz + hd, u2, v1, nx, ny, nz);
|
|
205
|
+
addVertex(ox - hw, oy + hh, oz - hd, u1, v1, nx, ny, nz);
|
|
206
|
+
addFaceIndices();
|
|
207
|
+
}
|
|
208
|
+
{
|
|
209
|
+
const [u1, v1, u2, v2] = normalizeUV(uv.left);
|
|
210
|
+
const [nx, ny, nz] = FACE_NORMALS[Face.Right];
|
|
211
|
+
addVertex(ox + hw, oy - hh, oz + hd, u1, v2, nx, ny, nz);
|
|
212
|
+
addVertex(ox + hw, oy - hh, oz - hd, u2, v2, nx, ny, nz);
|
|
213
|
+
addVertex(ox + hw, oy + hh, oz - hd, u2, v1, nx, ny, nz);
|
|
214
|
+
addVertex(ox + hw, oy + hh, oz + hd, u1, v1, nx, ny, nz);
|
|
215
|
+
addFaceIndices();
|
|
216
|
+
}
|
|
217
|
+
{
|
|
218
|
+
const [u1, v1, u2, v2] = normalizeUV(uv.top);
|
|
219
|
+
const [nx, ny, nz] = FACE_NORMALS[Face.Top];
|
|
220
|
+
addVertex(ox - hw, oy + hh, oz + hd, u1, v2, nx, ny, nz);
|
|
221
|
+
addVertex(ox + hw, oy + hh, oz + hd, u2, v2, nx, ny, nz);
|
|
222
|
+
addVertex(ox + hw, oy + hh, oz - hd, u2, v1, nx, ny, nz);
|
|
223
|
+
addVertex(ox - hw, oy + hh, oz - hd, u1, v1, nx, ny, nz);
|
|
224
|
+
addFaceIndices();
|
|
225
|
+
}
|
|
226
|
+
{
|
|
227
|
+
const [u1, v1, u2, v2] = normalizeUV(uv.bottom);
|
|
228
|
+
const [nx, ny, nz] = FACE_NORMALS[Face.Bottom];
|
|
229
|
+
addVertex(ox - hw, oy - hh, oz - hd, u1, v1, nx, ny, nz);
|
|
230
|
+
addVertex(ox + hw, oy - hh, oz - hd, u2, v1, nx, ny, nz);
|
|
231
|
+
addVertex(ox + hw, oy - hh, oz + hd, u2, v2, nx, ny, nz);
|
|
232
|
+
addVertex(ox - hw, oy - hh, oz + hd, u1, v2, nx, ny, nz);
|
|
233
|
+
addFaceIndices();
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
return {
|
|
237
|
+
vertices,
|
|
238
|
+
indices,
|
|
239
|
+
vertexCount,
|
|
240
|
+
indexCount
|
|
241
|
+
};
|
|
242
|
+
}
|
|
243
|
+
/**
|
|
244
|
+
* Create box geometry with UV mapping for skin parts
|
|
245
|
+
*
|
|
246
|
+
* @param size - Box dimensions [width, height, depth]
|
|
247
|
+
* @param uv - UV mapping for each face (in pixels, 64x64 texture)
|
|
248
|
+
* @param boneIndex - Bone index for skeletal animation
|
|
249
|
+
* @param offset - Position offset from bone origin
|
|
250
|
+
* @param inflate - Inflation amount (for overlay layers)
|
|
251
|
+
*/
|
|
252
|
+
function createBoxGeometry(size, uv, boneIndex, offset = [
|
|
253
|
+
0,
|
|
254
|
+
0,
|
|
255
|
+
0
|
|
256
|
+
], inflate = 0) {
|
|
257
|
+
return createBoxGeometryCore(size, uv, boneIndex, offset, {
|
|
258
|
+
inflate,
|
|
259
|
+
textureWidth: SKIN_TEXTURE_WIDTH,
|
|
260
|
+
textureHeight: SKIN_TEXTURE_HEIGHT,
|
|
261
|
+
capeUVMode: false
|
|
262
|
+
});
|
|
263
|
+
}
|
|
264
|
+
/**
|
|
265
|
+
* Create box geometry for cape/elytra with 64x32 texture
|
|
266
|
+
*
|
|
267
|
+
* @param size - Box dimensions [width, height, depth]
|
|
268
|
+
* @param uv - UV mapping for each face (in pixels, 64x32 texture)
|
|
269
|
+
* @param boneIndex - Bone index for skeletal animation
|
|
270
|
+
* @param offset - Position offset from bone origin
|
|
271
|
+
* @param mirrorX - Mirror the geometry along X axis (for right elytra wing)
|
|
272
|
+
*/
|
|
273
|
+
function createCapeBoxGeometry(size, uv, boneIndex, offset = [
|
|
274
|
+
0,
|
|
275
|
+
0,
|
|
276
|
+
0
|
|
277
|
+
], mirrorX = false) {
|
|
278
|
+
return createBoxGeometryCore(size, uv, boneIndex, offset, {
|
|
279
|
+
mirrorX,
|
|
280
|
+
textureWidth: CAPE_TEXTURE_WIDTH,
|
|
281
|
+
textureHeight: CAPE_TEXTURE_HEIGHT,
|
|
282
|
+
capeUVMode: true
|
|
283
|
+
});
|
|
284
|
+
}
|
|
285
|
+
/**
|
|
286
|
+
* Merge multiple box geometries into one
|
|
287
|
+
*/
|
|
288
|
+
function mergeGeometries(geometries) {
|
|
289
|
+
let totalVertices = 0;
|
|
290
|
+
let totalIndices = 0;
|
|
291
|
+
for (const geo of geometries) {
|
|
292
|
+
totalVertices += geo.vertexCount;
|
|
293
|
+
totalIndices += geo.indexCount;
|
|
294
|
+
}
|
|
295
|
+
const vertices = new Float32Array(totalVertices * VERTEX_STRIDE);
|
|
296
|
+
const indices = new Uint16Array(totalIndices);
|
|
297
|
+
let vertexOffset = 0;
|
|
298
|
+
let indexOffset = 0;
|
|
299
|
+
let baseVertex = 0;
|
|
300
|
+
for (const geo of geometries) {
|
|
301
|
+
vertices.set(geo.vertices, vertexOffset);
|
|
302
|
+
vertexOffset += geo.vertices.length;
|
|
303
|
+
for (let i = 0; i < geo.indexCount; i++) indices[indexOffset++] = geo.indices[i] + baseVertex;
|
|
304
|
+
baseVertex += geo.vertexCount;
|
|
305
|
+
}
|
|
306
|
+
return {
|
|
307
|
+
vertices,
|
|
308
|
+
indices,
|
|
309
|
+
vertexCount: totalVertices,
|
|
310
|
+
indexCount: totalIndices
|
|
311
|
+
};
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
//#endregion
|
|
315
|
+
export { createBoxGeometry, createCapeBoxGeometry, mergeGeometries };
|
|
316
|
+
//# sourceMappingURL=BoxGeometry.mjs.map
|