@erik9994857/cag 2.0.2 → 2.0.4
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/package.json +1 -1
- package/src/api/model-api.js +43 -2
- package/src/models/uv-mapper.js +4 -4
- package/src/runtime/electron-runner.js +10 -29
package/package.json
CHANGED
package/src/api/model-api.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
const path = require("path");
|
|
2
2
|
const fs = require("fs");
|
|
3
|
+
const UVMapper = require("../models/uv-mapper");
|
|
3
4
|
|
|
4
5
|
class ModelAPI {
|
|
5
6
|
constructor(resourceMap, defaultModelsPath) {
|
|
@@ -122,6 +123,9 @@ class ModelAPI {
|
|
|
122
123
|
|
|
123
124
|
const uvMappings = [];
|
|
124
125
|
|
|
126
|
+
const useBoxUV = !!data.box_uv;
|
|
127
|
+
const uvMapper = new UVMapper(geometry.resolution);
|
|
128
|
+
|
|
125
129
|
if (data.elements && Array.isArray(data.elements)) {
|
|
126
130
|
for (const element of data.elements) {
|
|
127
131
|
const geomElement = {
|
|
@@ -133,23 +137,60 @@ class ModelAPI {
|
|
|
133
137
|
faces: {}
|
|
134
138
|
};
|
|
135
139
|
|
|
140
|
+
const needsAutoUV = useBoxUV || (element.box_uv !== undefined && element.box_uv);
|
|
141
|
+
let autoUVs = null;
|
|
142
|
+
if (needsAutoUV) {
|
|
143
|
+
autoUVs = uvMapper.autoMap(geomElement.from, geomElement.to);
|
|
144
|
+
}
|
|
145
|
+
|
|
136
146
|
if (element.faces) {
|
|
137
147
|
const faceNames = ["north", "south", "east", "west", "up", "down"];
|
|
138
148
|
for (const faceName of faceNames) {
|
|
139
149
|
if (element.faces[faceName]) {
|
|
140
150
|
const face = element.faces[faceName];
|
|
151
|
+
let faceUV = face.uv;
|
|
152
|
+
|
|
153
|
+
if (!faceUV || !Array.isArray(faceUV) || faceUV.length < 4) {
|
|
154
|
+
faceUV = autoUVs ? autoUVs[faceName] : [0, 0, 16, 16];
|
|
155
|
+
}
|
|
156
|
+
|
|
141
157
|
geomElement.faces[faceName] = {
|
|
142
|
-
uv:
|
|
158
|
+
uv: faceUV,
|
|
143
159
|
texture: face.texture !== undefined ? face.texture : 0
|
|
144
160
|
};
|
|
145
161
|
uvMappings.push({
|
|
146
162
|
element: geomElement.name,
|
|
147
163
|
face: faceName,
|
|
148
|
-
uv:
|
|
164
|
+
uv: faceUV,
|
|
149
165
|
textureIndex: face.texture !== undefined ? face.texture : 0
|
|
150
166
|
});
|
|
167
|
+
} else if (needsAutoUV && autoUVs) {
|
|
168
|
+
geomElement.faces[faceName] = {
|
|
169
|
+
uv: autoUVs[faceName],
|
|
170
|
+
texture: 0
|
|
171
|
+
};
|
|
172
|
+
uvMappings.push({
|
|
173
|
+
element: geomElement.name,
|
|
174
|
+
face: faceName,
|
|
175
|
+
uv: autoUVs[faceName],
|
|
176
|
+
textureIndex: 0
|
|
177
|
+
});
|
|
151
178
|
}
|
|
152
179
|
}
|
|
180
|
+
} else if (needsAutoUV && autoUVs) {
|
|
181
|
+
const faceNames = ["north", "south", "east", "west", "up", "down"];
|
|
182
|
+
for (const faceName of faceNames) {
|
|
183
|
+
geomElement.faces[faceName] = {
|
|
184
|
+
uv: autoUVs[faceName],
|
|
185
|
+
texture: 0
|
|
186
|
+
};
|
|
187
|
+
uvMappings.push({
|
|
188
|
+
element: geomElement.name,
|
|
189
|
+
face: faceName,
|
|
190
|
+
uv: autoUVs[faceName],
|
|
191
|
+
textureIndex: 0
|
|
192
|
+
});
|
|
193
|
+
}
|
|
153
194
|
}
|
|
154
195
|
|
|
155
196
|
geometry.elements.push(geomElement);
|
package/src/models/uv-mapper.js
CHANGED
|
@@ -258,10 +258,10 @@ class UVMapper {
|
|
|
258
258
|
var sizeZ = Math.abs(elementTo[2] - elementFrom[2]);
|
|
259
259
|
|
|
260
260
|
return {
|
|
261
|
-
north: [sizeZ,
|
|
262
|
-
south: [sizeZ + sizeX + sizeZ,
|
|
263
|
-
east: [0,
|
|
264
|
-
west: [sizeZ + sizeX,
|
|
261
|
+
north: [sizeZ, sizeZ, sizeZ + sizeX, sizeZ + sizeY],
|
|
262
|
+
south: [sizeZ + sizeX + sizeZ, sizeZ, sizeZ + sizeX + sizeZ + sizeX, sizeZ + sizeY],
|
|
263
|
+
east: [0, sizeZ, sizeZ, sizeZ + sizeY],
|
|
264
|
+
west: [sizeZ + sizeX, sizeZ, sizeZ + sizeX + sizeZ, sizeZ + sizeY],
|
|
265
265
|
up: [sizeZ, 0, sizeZ + sizeX, sizeZ],
|
|
266
266
|
down: [sizeZ + sizeX, 0, sizeZ + sizeX + sizeX, sizeZ]
|
|
267
267
|
};
|
|
@@ -296,20 +296,25 @@ ElectronRunner.prototype.getRendererSource = function () {
|
|
|
296
296
|
js.push("}");
|
|
297
297
|
js.push("");
|
|
298
298
|
|
|
299
|
+
// Flip UV V-axis for side faces (v0/v1 are bottom vertices but addFace assigns fuv[1] to them)
|
|
300
|
+
js.push("function flipV(uv) { return [uv[0], uv[3], uv[2], uv[1]]; }");
|
|
301
|
+
js.push("");
|
|
302
|
+
|
|
299
303
|
// Build mesh for a chunk
|
|
300
304
|
js.push("function buildChunkMesh(blocks, blockMap) {");
|
|
301
305
|
js.push(" var pos = [], uvArr = [], nrm = [];");
|
|
302
306
|
js.push(" var uv = getModelUVs('Grass');");
|
|
307
|
+
js.push(" var sN = flipV(uv.north), sS = flipV(uv.south), sE = flipV(uv.east), sW = flipV(uv.west);");
|
|
303
308
|
js.push(" for (var i = 0; i < blocks.length; i++) {");
|
|
304
309
|
js.push(" var b = blocks[i];");
|
|
305
310
|
js.push(" var x = b.x, y = b.y, z = b.z;");
|
|
306
311
|
js.push(" var k = function(bx,by,bz) { return bx+','+by+','+bz; };");
|
|
307
312
|
js.push(" if (!blockMap[k(x,y+1,z)]) addFace(pos,uvArr,nrm, [x,y+1,z],[x+1,y+1,z],[x+1,y+1,z+1],[x,y+1,z+1], uv.up, [0,1,0]);");
|
|
308
313
|
js.push(" if (!blockMap[k(x,y-1,z)]) addFace(pos,uvArr,nrm, [x,y,z+1],[x+1,y,z+1],[x+1,y,z],[x,y,z], uv.down, [0,-1,0]);");
|
|
309
|
-
js.push(" if (!blockMap[k(x,y,z-1)]) addFace(pos,uvArr,nrm, [x,y,z],[x+1,y,z],[x+1,y+1,z],[x,y+1,z],
|
|
310
|
-
js.push(" if (!blockMap[k(x,y,z+1)]) addFace(pos,uvArr,nrm, [x+1,y,z+1],[x,y,z+1],[x,y+1,z+1],[x+1,y+1,z+1],
|
|
311
|
-
js.push(" if (!blockMap[k(x+1,y,z)]) addFace(pos,uvArr,nrm, [x+1,y,z],[x+1,y,z+1],[x+1,y+1,z+1],[x+1,y+1,z],
|
|
312
|
-
js.push(" if (!blockMap[k(x-1,y,z)]) addFace(pos,uvArr,nrm, [x,y,z+1],[x,y,z],[x,y+1,z],[x,y+1,z+1],
|
|
314
|
+
js.push(" if (!blockMap[k(x,y,z-1)]) addFace(pos,uvArr,nrm, [x,y,z],[x+1,y,z],[x+1,y+1,z],[x,y+1,z], sN, [0,0,-1]);");
|
|
315
|
+
js.push(" if (!blockMap[k(x,y,z+1)]) addFace(pos,uvArr,nrm, [x+1,y,z+1],[x,y,z+1],[x,y+1,z+1],[x+1,y+1,z+1], sS, [0,0,1]);");
|
|
316
|
+
js.push(" if (!blockMap[k(x+1,y,z)]) addFace(pos,uvArr,nrm, [x+1,y,z],[x+1,y,z+1],[x+1,y+1,z+1],[x+1,y+1,z], sE, [1,0,0]);");
|
|
317
|
+
js.push(" if (!blockMap[k(x-1,y,z)]) addFace(pos,uvArr,nrm, [x,y,z+1],[x,y,z],[x,y+1,z],[x,y+1,z+1], sW, [-1,0,0]);");
|
|
313
318
|
js.push(" }");
|
|
314
319
|
js.push(" return { positions: pos, uvs: uvArr, normals: nrm };");
|
|
315
320
|
js.push("}");
|
|
@@ -585,28 +590,6 @@ ElectronRunner.prototype.getRendererSource = function () {
|
|
|
585
590
|
js.push("};");
|
|
586
591
|
js.push("");
|
|
587
592
|
|
|
588
|
-
// HUD
|
|
589
|
-
js.push("game.updateHUD = function () {");
|
|
590
|
-
js.push(" var pcx = Math.floor(this.camX / CHUNK_SIZE);");
|
|
591
|
-
js.push(" var pcz = Math.floor(this.camZ / CHUNK_SIZE);");
|
|
592
|
-
js.push(" var loadedCount = Object.keys(this.chunks).length;");
|
|
593
|
-
js.push(" var sprint = this.keys['ShiftLeft'] || this.keys['ShiftRight'];");
|
|
594
|
-
js.push(" var html = '<div class=\"hud-title\">' + INFO_ID + '</div>';");
|
|
595
|
-
js.push(" html += '<div>v' + INFO_VERSION + '</div>';");
|
|
596
|
-
js.push(" html += '<div class=\"hud-sep\"></div>';");
|
|
597
|
-
js.push(" html += '<div>FPS: ' + this.fps + '</div>';");
|
|
598
|
-
js.push(" html += '<div>Triangles: ' + Math.floor(this.totalVerts / 3) + '</div>';");
|
|
599
|
-
js.push(" html += '<div>Blocks: ' + this.totalBlocks + '</div>';");
|
|
600
|
-
js.push(" html += '<div>Chunks: ' + loadedCount + '</div>';");
|
|
601
|
-
js.push(" html += '<div class=\"hud-sep\"></div>';");
|
|
602
|
-
js.push(" html += '<div>X: ' + this.camX.toFixed(1) + '</div>';");
|
|
603
|
-
js.push(" html += '<div>Y: ' + this.camY.toFixed(1) + '</div>';");
|
|
604
|
-
js.push(" html += '<div>Z: ' + this.camZ.toFixed(1) + '</div>';");
|
|
605
|
-
js.push(" html += '<div>Chunk: ' + pcx + ', ' + pcz + '</div>';");
|
|
606
|
-
js.push(" html += '<div class=\"hud-sep\"></div>';");
|
|
607
|
-
js.push(" html += '<div>Sprint: ' + (sprint ? 'ON' : 'OFF') + '</div>';");
|
|
608
|
-
js.push(" document.getElementById('hud-info').innerHTML = html;");
|
|
609
|
-
js.push("};");
|
|
610
593
|
js.push("");
|
|
611
594
|
|
|
612
595
|
// Game loop
|
|
@@ -616,7 +599,6 @@ ElectronRunner.prototype.getRendererSource = function () {
|
|
|
616
599
|
js.push(" game.update();");
|
|
617
600
|
js.push(" updateChunks();");
|
|
618
601
|
js.push(" game.render();");
|
|
619
|
-
js.push(" game.updateHUD();");
|
|
620
602
|
js.push("};");
|
|
621
603
|
js.push("");
|
|
622
604
|
|
|
@@ -628,8 +610,7 @@ ElectronRunner.prototype.getRendererSource = function () {
|
|
|
628
610
|
html += "<style>\n" + css + "\n</style>\n";
|
|
629
611
|
html += "</head>\n<body>\n";
|
|
630
612
|
html += "<div id='crosshair' style='display:none'></div>\n";
|
|
631
|
-
html += "
|
|
632
|
-
html += "<div id='controls-hint'><b>WASD</b> Move <b>Mouse</b> Look <b>Space</b> Jump <b>Shift</b> Sprint <b>F11</b> Fullscreen <b>Esc</b> Release</div>\n";
|
|
613
|
+
html += "";
|
|
633
614
|
html += "<canvas id='cag-canvas'></canvas>\n";
|
|
634
615
|
html += "<script>\n" + js.join("\n") + "\n</script>\n";
|
|
635
616
|
html += "</body>\n</html>";
|