mirror of
https://github.com/Azgaar/Fantasy-Map-Generator.git
synced 2025-12-22 12:01:23 +01:00
Subdivision added. Removed toggle wireframe as an option.
Reverted to previous rendering method.
This commit is contained in:
parent
a2ba10be78
commit
a591b8eebd
5 changed files with 217 additions and 180 deletions
31
index.html
31
index.html
|
|
@ -5673,14 +5673,7 @@
|
||||||
<input id="options3dSunZ" type="number" min="-1500" max="1500" step="100" style="width: 4.7em" />
|
<input id="options3dSunZ" type="number" min="-1500" max="1500" step="100" style="width: 4.7em" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div data-tip="Set Sun Color" id="options3dSunColorSection">
|
|
||||||
<span>Sun Color:</span
|
|
||||||
><input
|
|
||||||
id="options3dSunColor"
|
|
||||||
type="color"
|
|
||||||
style="width: 4.4em; height: 1em; border: 0; padding: 0; margin: 0 0.2em"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div data-tip="Toggle 3d labels" style="margin: 0.6em 0 0.3em -0.2em">
|
<div data-tip="Toggle 3d labels" style="margin: 0.6em 0 0.3em -0.2em">
|
||||||
<input id="options3dMeshLabels3d" class="checkbox" type="checkbox" />
|
<input id="options3dMeshLabels3d" class="checkbox" type="checkbox" />
|
||||||
|
|
@ -5692,9 +5685,23 @@
|
||||||
<label for="options3dMeshSkyMode" class="checkbox-label"><i>Show sky and extend water</i></label>
|
<label for="options3dMeshSkyMode" class="checkbox-label"><i>Show sky and extend water</i></label>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div data-tip="Toggle wireframe mode, generally used for debugging." style="margin: 0.6em 0 0.3em -0.2em">
|
<div data-tip="Toggle 3d subdivision. Increases the polygon count. Opening this will take some time. WARNING: Can smooth the sharp points in progress." style="margin: 0.6em 0 0.3em -0.2em">
|
||||||
|
<input id="options3dSubdivide" class="checkbox" type="checkbox" />
|
||||||
|
<label for="options3dSubdivide" class="checkbox-label"><i>Subdivide Model.</i></label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- <div data-tip="Toggle wireframe mode, generally used for debugging." style="margin: 0.6em 0 0.3em -0.2em">
|
||||||
<input id="options3dMeshWireframeMode" class="checkbox" type="checkbox" />
|
<input id="options3dMeshWireframeMode" class="checkbox" type="checkbox" />
|
||||||
<label for="options3dMeshWireframeMode" class="checkbox-label"><i>Show mesh material as wireframe</i></label>
|
<label for="options3dMeshWireframeMode" class="checkbox-label"><i>Show mesh material as wireframe</i></label>
|
||||||
|
</div> -->
|
||||||
|
|
||||||
|
<div data-tip="Set Sun Color" id="options3dSunColorSection">
|
||||||
|
<span>Sun Color:</span
|
||||||
|
><input
|
||||||
|
id="options3dSunColor"
|
||||||
|
type="color"
|
||||||
|
style="width: 4.4em; height: 1em; border: 0; padding: 0; margin: 0 0.2em"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div data-tip="Set sky and water color" id="options3dColorSection" style="display: none">
|
<div data-tip="Set sky and water color" id="options3dColorSection" style="display: none">
|
||||||
|
|
@ -7913,7 +7920,7 @@
|
||||||
<script src="modules/ui/stylePresets.js?v=1.89.11"></script>
|
<script src="modules/ui/stylePresets.js?v=1.89.11"></script>
|
||||||
|
|
||||||
<script src="modules/ui/general.js?v=1.87.03"></script>
|
<script src="modules/ui/general.js?v=1.87.03"></script>
|
||||||
<script src="modules/ui/options.js?v=1.89.20"></script>
|
<script src="modules/ui/options.js?v=1.89.35"></script>
|
||||||
<script src="main.js?v=1.89.32"></script>
|
<script src="main.js?v=1.89.32"></script>
|
||||||
|
|
||||||
<script defer src="modules/relief-icons.js"></script>
|
<script defer src="modules/relief-icons.js"></script>
|
||||||
|
|
@ -7949,14 +7956,14 @@
|
||||||
<script defer src="modules/ui/battle-screen.js"></script>
|
<script defer src="modules/ui/battle-screen.js"></script>
|
||||||
<script defer src="modules/ui/emblems-editor.js?v=1.89.21"></script>
|
<script defer src="modules/ui/emblems-editor.js?v=1.89.21"></script>
|
||||||
<script defer src="modules/ui/markers-editor.js"></script>
|
<script defer src="modules/ui/markers-editor.js"></script>
|
||||||
<script defer src="modules/ui/3d.js?v=1.89.33"></script>
|
<script defer src="modules/ui/3d.js?v=1.89.35"></script>
|
||||||
<script defer src="modules/ui/submap.js"></script>
|
<script defer src="modules/ui/submap.js"></script>
|
||||||
<script defer src="modules/ui/hotkeys.js?v=1.88.00"></script>
|
<script defer src="modules/ui/hotkeys.js?v=1.88.00"></script>
|
||||||
<script defer src="modules/coa-renderer.js?v=1.87.08"></script>
|
<script defer src="modules/coa-renderer.js?v=1.87.08"></script>
|
||||||
<script defer src="libs/rgbquant.min.js"></script>
|
<script defer src="libs/rgbquant.min.js"></script>
|
||||||
<script defer src="libs/jquery.ui.touch-punch.min.js"></script>
|
<script defer src="libs/jquery.ui.touch-punch.min.js"></script>
|
||||||
<script defer src="libs/three.min.js"></script>
|
<script defer src="libs/three.min.js"></script>
|
||||||
<script defer src="libs/LoopSubdivision.js"></script>
|
<script defer src="libs/loopSubdivision.js"></script>
|
||||||
|
|
||||||
<script defer src="modules/io/save.js?v=1.89.29"></script>
|
<script defer src="modules/io/save.js?v=1.89.29"></script>
|
||||||
<script defer src="modules/io/load.js?v=1.89.30"></script>
|
<script defer src="modules/io/load.js?v=1.89.30"></script>
|
||||||
|
|
|
||||||
|
|
@ -67,47 +67,46 @@
|
||||||
//
|
//
|
||||||
/////////////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
const loopSubdivision = {};
|
||||||
|
(()=>{
|
||||||
|
///// Constants
|
||||||
|
|
||||||
|
const POSITION_DECIMALS = 2;
|
||||||
|
|
||||||
///// Constants
|
///// Local Variables
|
||||||
|
|
||||||
const POSITION_DECIMALS = 2;
|
const _average = new THREE.Vector3();
|
||||||
|
const _center = new THREE.Vector3();
|
||||||
|
const _midpoint = new THREE.Vector3();
|
||||||
|
const _normal = new THREE.Vector3();
|
||||||
|
const _temp = new THREE.Vector3();
|
||||||
|
|
||||||
///// Local Variables
|
const _vector0 = new THREE.Vector3(); // .Vector4();
|
||||||
|
const _vector1 = new THREE.Vector3(); // .Vector4();
|
||||||
|
const _vector2 = new THREE.Vector3(); // .Vector4();
|
||||||
|
const _vec0to1 = new THREE.Vector3();
|
||||||
|
const _vec1to2 = new THREE.Vector3();
|
||||||
|
const _vec2to0 = new THREE.Vector3();
|
||||||
|
|
||||||
const _average = new THREE.Vector3();
|
const _position = [
|
||||||
const _center = new THREE.Vector3();
|
new THREE.Vector3(),
|
||||||
const _midpoint = new THREE.Vector3();
|
new THREE.Vector3(),
|
||||||
const _normal = new THREE.Vector3();
|
new THREE.Vector3(),
|
||||||
const _temp = new THREE.Vector3();
|
];
|
||||||
|
|
||||||
const _vector0 = new THREE.Vector3(); // .Vector4();
|
const _vertex = [
|
||||||
const _vector1 = new THREE.Vector3(); // .Vector4();
|
new THREE.Vector3(),
|
||||||
const _vector2 = new THREE.Vector3(); // .Vector4();
|
new THREE.Vector3(),
|
||||||
const _vec0to1 = new THREE.Vector3();
|
new THREE.Vector3(),
|
||||||
const _vec1to2 = new THREE.Vector3();
|
];
|
||||||
const _vec2to0 = new THREE.Vector3();
|
|
||||||
|
|
||||||
const _position = [
|
const _triangle = new THREE.Triangle();
|
||||||
new THREE.Vector3(),
|
|
||||||
new THREE.Vector3(),
|
|
||||||
new THREE.Vector3(),
|
|
||||||
];
|
|
||||||
|
|
||||||
const _vertex = [
|
/////////////////////////////////////////////////////////////////////////////////////
|
||||||
new THREE.Vector3(),
|
///// Loop Subdivision Surface
|
||||||
new THREE.Vector3(),
|
/////////////////////////////////////////////////////////////////////////////////////
|
||||||
new THREE.Vector3(),
|
|
||||||
];
|
|
||||||
|
|
||||||
const _triangle = new THREE.Triangle();
|
/** Loop subdivision surface modifier for use with modern three.js BufferGeometry */
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
///// Loop Subdivision Surface
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
/** Loop subdivision surface modifier for use with modern three.js BufferGeometry */
|
|
||||||
class LoopSubdivision {
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////////////
|
||||||
///// Modify
|
///// Modify
|
||||||
|
|
@ -128,8 +127,8 @@ class LoopSubdivision {
|
||||||
* @param {Boolean} flatOnly - If true, subdivision generates triangles, but does not modify positions
|
* @param {Boolean} flatOnly - If true, subdivision generates triangles, but does not modify positions
|
||||||
* @param {Number} maxTriangles - If geometry contains more than this many triangles, subdivision will not continue
|
* @param {Number} maxTriangles - If geometry contains more than this many triangles, subdivision will not continue
|
||||||
*/
|
*/
|
||||||
static modify(bufferGeometry, iterations = 1, params = {}) {
|
function modify(bufferGeometry, iterations = 1, params = {}) {
|
||||||
if (arguments.length > 3) console.warn(`LoopSubdivision.modify() now uses a parameter object. See readme for more info!`);
|
if (arguments.length > 3) console.warn(`modify() now uses a parameter object. See readme for more info!`);
|
||||||
|
|
||||||
if (typeof params !== 'object') params = {};
|
if (typeof params !== 'object') params = {};
|
||||||
|
|
||||||
|
|
@ -141,12 +140,12 @@ class LoopSubdivision {
|
||||||
if (params.maxTriangles === undefined) params.maxTriangles = Infinity;
|
if (params.maxTriangles === undefined) params.maxTriangles = Infinity;
|
||||||
|
|
||||||
///// Geometries
|
///// Geometries
|
||||||
if (! verifyGeometry(bufferGeometry)) return bufferGeometry;
|
if (!verifyGeometry(bufferGeometry)) return bufferGeometry;
|
||||||
let modifiedGeometry = bufferGeometry.clone();
|
let modifiedGeometry = bufferGeometry.clone();
|
||||||
|
|
||||||
///// Presplit
|
///// Presplit
|
||||||
if (params.split) {
|
if (params.split) {
|
||||||
const splitGeometry = LoopSubdivision.edgeSplit(modifiedGeometry)
|
const splitGeometry = edgeSplit(modifiedGeometry)
|
||||||
modifiedGeometry.dispose();
|
modifiedGeometry.dispose();
|
||||||
modifiedGeometry = splitGeometry;
|
modifiedGeometry = splitGeometry;
|
||||||
}
|
}
|
||||||
|
|
@ -159,9 +158,9 @@ class LoopSubdivision {
|
||||||
|
|
||||||
// Subdivide
|
// Subdivide
|
||||||
if (params.flatOnly) {
|
if (params.flatOnly) {
|
||||||
subdividedGeometry = LoopSubdivision.flat(modifiedGeometry);
|
subdividedGeometry = flat(modifiedGeometry);
|
||||||
} else {
|
} else {
|
||||||
subdividedGeometry = LoopSubdivision.smooth(modifiedGeometry, params);
|
subdividedGeometry = smooth(modifiedGeometry, params);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Copy and Resize Groups
|
// Copy and Resize Groups
|
||||||
|
|
@ -178,7 +177,8 @@ class LoopSubdivision {
|
||||||
///// Return New Geometry
|
///// Return New Geometry
|
||||||
return modifiedGeometry;
|
return modifiedGeometry;
|
||||||
}
|
}
|
||||||
|
loopSubdivision.modify = modify;
|
||||||
|
console.log("Hello World");
|
||||||
/////////////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////////////
|
||||||
///// Split Hypotenuse
|
///// Split Hypotenuse
|
||||||
////////////////////
|
////////////////////
|
||||||
|
|
@ -188,10 +188,10 @@ class LoopSubdivision {
|
||||||
* Starts by splitting at longest shared edge, followed by splitting from that new center edge point to the
|
* Starts by splitting at longest shared edge, followed by splitting from that new center edge point to the
|
||||||
* center of any other shared edges.
|
* center of any other shared edges.
|
||||||
*/
|
*/
|
||||||
static edgeSplit(geometry) {
|
function edgeSplit(geometry) {
|
||||||
|
|
||||||
///// Geometries
|
///// Geometries
|
||||||
if (! verifyGeometry(geometry)) return geometry;
|
if (!verifyGeometry(geometry)) return geometry;
|
||||||
const existing = (geometry.index !== null) ? geometry.toNonIndexed() : geometry.clone();
|
const existing = (geometry.index !== null) ? geometry.toNonIndexed() : geometry.clone();
|
||||||
const split = new THREE.BufferGeometry();
|
const split = new THREE.BufferGeometry();
|
||||||
|
|
||||||
|
|
@ -219,8 +219,8 @@ class LoopSubdivision {
|
||||||
|
|
||||||
// Verify Area
|
// Verify Area
|
||||||
const triangleSize = _triangle.set(_vector0, _vector1, _vector2).getArea();
|
const triangleSize = _triangle.set(_vector0, _vector1, _vector2).getArea();
|
||||||
triangleExist.push(! fuzzy(triangleSize, 0));
|
triangleExist.push(!fuzzy(triangleSize, 0));
|
||||||
if (! triangleExist[i / 3]) {
|
if (!triangleExist[i / 3]) {
|
||||||
triangleEdgeHashes.push([]);
|
triangleEdgeHashes.push([]);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
@ -243,11 +243,11 @@ class LoopSubdivision {
|
||||||
const index = i / 3;
|
const index = i / 3;
|
||||||
for (let j = 0; j < hashes.length; j++) {
|
for (let j = 0; j < hashes.length; j++) {
|
||||||
// Attach Triangle Index to Edge Hash
|
// Attach Triangle Index to Edge Hash
|
||||||
if (! edgeHashToTriangle[hashes[j]]) edgeHashToTriangle[hashes[j]] = [];
|
if (!edgeHashToTriangle[hashes[j]]) edgeHashToTriangle[hashes[j]] = [];
|
||||||
edgeHashToTriangle[hashes[j]].push(index);
|
edgeHashToTriangle[hashes[j]].push(index);
|
||||||
|
|
||||||
// Edge Length
|
// Edge Length
|
||||||
if (! edgeLength[hashes[j]]) {
|
if (!edgeLength[hashes[j]]) {
|
||||||
if (j === 0 || j === 1) edgeLength[hashes[j]] = _vector0.distanceTo(_vector1);
|
if (j === 0 || j === 1) edgeLength[hashes[j]] = _vector0.distanceTo(_vector1);
|
||||||
if (j === 2 || j === 3) edgeLength[hashes[j]] = _vector1.distanceTo(_vector2);
|
if (j === 2 || j === 3) edgeLength[hashes[j]] = _vector1.distanceTo(_vector2);
|
||||||
if (j === 4 || j === 5) edgeLength[hashes[j]] = _vector2.distanceTo(_vector0);
|
if (j === 4 || j === 5) edgeLength[hashes[j]] = _vector2.distanceTo(_vector0);
|
||||||
|
|
@ -255,13 +255,13 @@ class LoopSubdivision {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Triangle Edge Reference
|
// Triangle Edge Reference
|
||||||
triangleEdgeHashes.push([ hashes[0], hashes[2], hashes[4] ]);
|
triangleEdgeHashes.push([hashes[0], hashes[2], hashes[4]]);
|
||||||
}
|
}
|
||||||
|
|
||||||
///// Build Geometry, Set Attributes
|
///// Build Geometry, Set Attributes
|
||||||
attributeList.forEach((attributeName) => {
|
attributeList.forEach((attributeName) => {
|
||||||
const attribute = existing.getAttribute(attributeName);
|
const attribute = existing.getAttribute(attributeName);
|
||||||
if (! attribute) return;
|
if (!attribute) return;
|
||||||
const floatArray = splitAttribute(attribute, attributeName);
|
const floatArray = splitAttribute(attribute, attributeName);
|
||||||
split.setAttribute(attributeName, new THREE.BufferAttribute(floatArray, attribute.itemSize));
|
split.setAttribute(attributeName, new THREE.BufferAttribute(floatArray, attribute.itemSize));
|
||||||
});
|
});
|
||||||
|
|
@ -292,7 +292,7 @@ class LoopSubdivision {
|
||||||
const arrayLength = (vertexCount * attribute.itemSize) * newTriangles;
|
const arrayLength = (vertexCount * attribute.itemSize) * newTriangles;
|
||||||
const floatArray = new attribute.array.constructor(arrayLength);
|
const floatArray = new attribute.array.constructor(arrayLength);
|
||||||
|
|
||||||
const processGroups = (attributeName === 'position' && ! morph && existing.groups.length > 0);
|
const processGroups = (attributeName === 'position' && !morph && existing.groups.length > 0);
|
||||||
let groupStart = undefined, groupMaterial = undefined;
|
let groupStart = undefined, groupMaterial = undefined;
|
||||||
|
|
||||||
let index = 0;
|
let index = 0;
|
||||||
|
|
@ -301,7 +301,7 @@ class LoopSubdivision {
|
||||||
for (let i = 0; i < vertexCount; i += 3) {
|
for (let i = 0; i < vertexCount; i += 3) {
|
||||||
|
|
||||||
// Verify Triangle is Valid
|
// Verify Triangle is Valid
|
||||||
if (! triangleExist[i / 3]) {
|
if (!triangleExist[i / 3]) {
|
||||||
skipped += 3;
|
skipped += 3;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
@ -329,7 +329,7 @@ class LoopSubdivision {
|
||||||
if (sharedCount === 0) {
|
if (sharedCount === 0) {
|
||||||
setTriangle(floatArray, index, step, _vector0, _vector1, _vector2); index += (step * 3);
|
setTriangle(floatArray, index, step, _vector0, _vector1, _vector2); index += (step * 3);
|
||||||
|
|
||||||
// Shared Edges
|
// Shared Edges
|
||||||
} else {
|
} else {
|
||||||
const length0to1 = edgeLength[edgeHash0to1];
|
const length0to1 = edgeLength[edgeHash0to1];
|
||||||
const length1to2 = edgeLength[edgeHash1to2];
|
const length1to2 = edgeLength[edgeHash1to2];
|
||||||
|
|
@ -431,10 +431,10 @@ class LoopSubdivision {
|
||||||
////////////////////
|
////////////////////
|
||||||
|
|
||||||
/** Applies one iteration of Loop (flat) subdivision (1 triangle split into 4 triangles) */
|
/** Applies one iteration of Loop (flat) subdivision (1 triangle split into 4 triangles) */
|
||||||
static flat(geometry) {
|
function flat(geometry) {
|
||||||
|
|
||||||
///// Geometries
|
///// Geometries
|
||||||
if (! verifyGeometry(geometry)) return geometry;
|
if (!verifyGeometry(geometry)) return geometry;
|
||||||
const existing = (geometry.index !== null) ? geometry.toNonIndexed() : geometry.clone();
|
const existing = (geometry.index !== null) ? geometry.toNonIndexed() : geometry.clone();
|
||||||
const loop = new THREE.BufferGeometry();
|
const loop = new THREE.BufferGeometry();
|
||||||
|
|
||||||
|
|
@ -445,9 +445,9 @@ class LoopSubdivision {
|
||||||
///// Build Geometry
|
///// Build Geometry
|
||||||
attributeList.forEach((attributeName) => {
|
attributeList.forEach((attributeName) => {
|
||||||
const attribute = existing.getAttribute(attributeName);
|
const attribute = existing.getAttribute(attributeName);
|
||||||
if (! attribute) return;
|
if (!attribute) return;
|
||||||
|
|
||||||
loop.setAttribute(attributeName, LoopSubdivision.flatAttribute(attribute, vertexCount));
|
loop.setAttribute(attributeName, flatAttribute(attribute, vertexCount));
|
||||||
});
|
});
|
||||||
|
|
||||||
///// Morph Attributes
|
///// Morph Attributes
|
||||||
|
|
@ -457,9 +457,9 @@ class LoopSubdivision {
|
||||||
const morphAttribute = morphAttributes[attributeName];
|
const morphAttribute = morphAttributes[attributeName];
|
||||||
|
|
||||||
// Process Array of Float32BufferAttributes
|
// Process Array of Float32BufferAttributes
|
||||||
for (let i = 0, l = morphAttribute.length; i < l; i++) {
|
for (let i = 0, l = morphAttribute.length; i < l; i++) {
|
||||||
if (morphAttribute[i].count !== vertexCount) continue;
|
if (morphAttribute[i].count !== vertexCount) continue;
|
||||||
array.push(LoopSubdivision.flatAttribute(morphAttribute[i], vertexCount));
|
array.push(flatAttribute(morphAttribute[i], vertexCount));
|
||||||
}
|
}
|
||||||
loop.morphAttributes[attributeName] = array;
|
loop.morphAttributes[attributeName] = array;
|
||||||
}
|
}
|
||||||
|
|
@ -470,7 +470,7 @@ class LoopSubdivision {
|
||||||
return loop;
|
return loop;
|
||||||
}
|
}
|
||||||
|
|
||||||
static flatAttribute(attribute, vertexCount) {
|
function flatAttribute(attribute, vertexCount) {
|
||||||
const newTriangles = 4;
|
const newTriangles = 4;
|
||||||
const arrayLength = (vertexCount * attribute.itemSize) * newTriangles;
|
const arrayLength = (vertexCount * attribute.itemSize) * newTriangles;
|
||||||
const floatArray = new attribute.array.constructor(arrayLength);
|
const floatArray = new attribute.array.constructor(arrayLength);
|
||||||
|
|
@ -504,7 +504,7 @@ class LoopSubdivision {
|
||||||
////////////////////
|
////////////////////
|
||||||
|
|
||||||
/** Applies one iteration of Loop (smooth) subdivision (1 triangle split into 4 triangles) */
|
/** Applies one iteration of Loop (smooth) subdivision (1 triangle split into 4 triangles) */
|
||||||
static smooth(geometry, params = {}) {
|
function smooth(geometry, params = {}) {
|
||||||
|
|
||||||
if (typeof params !== 'object') params = {};
|
if (typeof params !== 'object') params = {};
|
||||||
|
|
||||||
|
|
@ -513,34 +513,34 @@ class LoopSubdivision {
|
||||||
if (params.preserveEdges === undefined) params.preserveEdges = false;
|
if (params.preserveEdges === undefined) params.preserveEdges = false;
|
||||||
|
|
||||||
///// Geometries
|
///// Geometries
|
||||||
if (! verifyGeometry(geometry)) return geometry;
|
if (!verifyGeometry(geometry)) return geometry;
|
||||||
const existing = (geometry.index !== null) ? geometry.toNonIndexed() : geometry.clone();
|
const existing = (geometry.index !== null) ? geometry.toNonIndexed() : geometry.clone();
|
||||||
const flat = LoopSubdivision.flat(existing);
|
const flatGeometry = flat(existing);
|
||||||
const loop = new THREE.BufferGeometry();
|
const loop = new THREE.BufferGeometry();
|
||||||
|
|
||||||
///// Attributes
|
///// Attributes
|
||||||
const attributeList = gatherAttributes(existing);
|
const attributeList = gatherAttributes(existing);
|
||||||
const vertexCount = existing.attributes.position.count;
|
const vertexCount = existing.attributes.position.count;
|
||||||
const posAttribute = existing.getAttribute('position');
|
const posAttribute = existing.getAttribute('position');
|
||||||
const flatPosition = flat.getAttribute('position');
|
const flatPosition = flatGeometry.getAttribute('position');
|
||||||
const hashToIndex = {}; // Position hash mapped to index values of same position
|
const hashToIndex = {}; // Position hash mapped to index values of same position
|
||||||
const existingNeighbors = {}; // Position hash mapped to existing vertex neighbors
|
const existingNeighbors = {}; // Position hash mapped to existing vertex neighbors
|
||||||
const flatOpposites = {}; // Position hash mapped to new edge point opposites
|
const flatOpposites = {}; // Position hash mapped to new edge point opposites
|
||||||
const existingEdges = {};
|
const existingEdges = {};
|
||||||
|
|
||||||
function addNeighbor(posHash, neighborHash, index) {
|
function addNeighbor(posHash, neighborHash, index) {
|
||||||
if (! existingNeighbors[posHash]) existingNeighbors[posHash] = {};
|
if (!existingNeighbors[posHash]) existingNeighbors[posHash] = {};
|
||||||
if (! existingNeighbors[posHash][neighborHash]) existingNeighbors[posHash][neighborHash] = [];
|
if (!existingNeighbors[posHash][neighborHash]) existingNeighbors[posHash][neighborHash] = [];
|
||||||
existingNeighbors[posHash][neighborHash].push(index);
|
existingNeighbors[posHash][neighborHash].push(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
function addOpposite(posHash, index) {
|
function addOpposite(posHash, index) {
|
||||||
if (! flatOpposites[posHash]) flatOpposites[posHash] = [];
|
if (!flatOpposites[posHash]) flatOpposites[posHash] = [];
|
||||||
flatOpposites[posHash].push(index);
|
flatOpposites[posHash].push(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
function addEdgePoint(posHash, edgeHash) {
|
function addEdgePoint(posHash, edgeHash) {
|
||||||
if (! existingEdges[posHash]) existingEdges[posHash] = new Set();
|
if (!existingEdges[posHash]) existingEdges[posHash] = new Set();
|
||||||
existingEdges[posHash].add(edgeHash);
|
existingEdges[posHash].add(edgeHash);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -579,16 +579,16 @@ class LoopSubdivision {
|
||||||
}
|
}
|
||||||
|
|
||||||
///// Flat Position to Index Map
|
///// Flat Position to Index Map
|
||||||
for (let i = 0; i < flat.attributes.position.count; i++) {
|
for (let i = 0; i < flatGeometry.attributes.position.count; i++) {
|
||||||
const posHash = hashFromVector(_temp.fromBufferAttribute(flatPosition, i));
|
const posHash = hashFromVector(_temp.fromBufferAttribute(flatPosition, i));
|
||||||
if (! hashToIndex[posHash]) hashToIndex[posHash] = [];
|
if (!hashToIndex[posHash]) hashToIndex[posHash] = [];
|
||||||
hashToIndex[posHash].push(i);
|
hashToIndex[posHash].push(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
///// Build Geometry, Set Attributes
|
///// Build Geometry, Set Attributes
|
||||||
attributeList.forEach((attributeName) => {
|
attributeList.forEach((attributeName) => {
|
||||||
const existingAttribute = existing.getAttribute(attributeName);
|
const existingAttribute = existing.getAttribute(attributeName);
|
||||||
const flatAttribute = flat.getAttribute(attributeName);
|
const flatAttribute = flatGeometry.getAttribute(attributeName);
|
||||||
if (existingAttribute === undefined || flatAttribute === undefined) return;
|
if (existingAttribute === undefined || flatAttribute === undefined) return;
|
||||||
|
|
||||||
const floatArray = subdivideAttribute(attributeName, existingAttribute, flatAttribute);
|
const floatArray = subdivideAttribute(attributeName, existingAttribute, flatAttribute);
|
||||||
|
|
@ -605,7 +605,7 @@ class LoopSubdivision {
|
||||||
for (let i = 0, l = morphAttribute.length; i < l; i++) {
|
for (let i = 0, l = morphAttribute.length; i < l; i++) {
|
||||||
if (morphAttribute[i].count !== vertexCount) continue;
|
if (morphAttribute[i].count !== vertexCount) continue;
|
||||||
const existingAttribute = morphAttribute[i];
|
const existingAttribute = morphAttribute[i];
|
||||||
const flatAttribute = LoopSubdivision.flatAttribute(morphAttribute[i], morphAttribute[i].count)
|
const flatAttribute = flatAttribute(morphAttribute[i], morphAttribute[i].count)
|
||||||
|
|
||||||
const floatArray = subdivideAttribute(attributeName, existingAttribute, flatAttribute);
|
const floatArray = subdivideAttribute(attributeName, existingAttribute, flatAttribute);
|
||||||
array.push(new THREE.BufferAttribute(floatArray, flatAttribute.itemSize));
|
array.push(new THREE.BufferAttribute(floatArray, flatAttribute.itemSize));
|
||||||
|
|
@ -615,7 +615,7 @@ class LoopSubdivision {
|
||||||
loop.morphTargetsRelative = existing.morphTargetsRelative;
|
loop.morphTargetsRelative = existing.morphTargetsRelative;
|
||||||
|
|
||||||
///// Clean Up
|
///// Clean Up
|
||||||
flat.dispose();
|
flatGeometry.dispose();
|
||||||
existing.dispose();
|
existing.dispose();
|
||||||
return loop;
|
return loop;
|
||||||
|
|
||||||
|
|
@ -623,17 +623,17 @@ class LoopSubdivision {
|
||||||
|
|
||||||
// Loop Subdivide Function
|
// Loop Subdivide Function
|
||||||
function subdivideAttribute(attributeName, existingAttribute, flatAttribute) {
|
function subdivideAttribute(attributeName, existingAttribute, flatAttribute) {
|
||||||
const arrayLength = (flat.attributes.position.count * flatAttribute.itemSize);
|
const arrayLength = (flatGeometry.attributes.position.count * flatAttribute.itemSize);
|
||||||
const floatArray = new existingAttribute.array.constructor(arrayLength);
|
const floatArray = new existingAttribute.array.constructor(arrayLength);
|
||||||
|
|
||||||
// Process Triangles
|
// Process Triangles
|
||||||
let index = 0;
|
let index = 0;
|
||||||
for (let i = 0; i < flat.attributes.position.count; i += 3) {
|
for (let i = 0; i < flatGeometry.attributes.position.count; i += 3) {
|
||||||
|
|
||||||
// Process Triangle Points
|
// Process Triangle Points
|
||||||
for (let v = 0; v < 3; v++) {
|
for (let v = 0; v < 3; v++) {
|
||||||
|
|
||||||
if (attributeName === 'uv' && ! params.uvSmooth) {
|
if (attributeName === 'uv' && !params.uvSmooth) {
|
||||||
|
|
||||||
_vertex[v].fromBufferAttribute(flatAttribute, i + v);
|
_vertex[v].fromBufferAttribute(flatAttribute, i + v);
|
||||||
|
|
||||||
|
|
@ -676,14 +676,14 @@ class LoopSubdivision {
|
||||||
for (const edgeHash of edgeSet) {
|
for (const edgeHash of edgeSet) {
|
||||||
if (flatOpposites[edgeHash].length % 2 !== 0) hasPair = false;
|
if (flatOpposites[edgeHash].length % 2 !== 0) hasPair = false;
|
||||||
}
|
}
|
||||||
if (! hasPair) continue;
|
if (!hasPair) continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Number of Neighbors
|
// Number of Neighbors
|
||||||
const k = Object.keys(neighbors).length;
|
const k = Object.keys(neighbors).length;
|
||||||
|
|
||||||
///// Loop's Formula
|
///// Loop's Formula
|
||||||
const beta = 1 / k * ((5/8) - Math.pow((3/8) + (1/4) * Math.cos(2 * Math.PI / k), 2));
|
const beta = 1 / k * ((5 / 8) - Math.pow((3 / 8) + (1 / 4) * Math.cos(2 * Math.PI / k), 2));
|
||||||
|
|
||||||
///// Warren's Formula
|
///// Warren's Formula
|
||||||
// const beta = (k > 3) ? 3 / (8 * k) : ((k === 3) ? 3 / 16 : 0);
|
// const beta = (k > 3) ? 3 / (8 * k) : ((k === 3) ? 3 / 16 : 0);
|
||||||
|
|
@ -708,7 +708,7 @@ class LoopSubdivision {
|
||||||
_vertex[v].add(_average);
|
_vertex[v].add(_average);
|
||||||
}
|
}
|
||||||
|
|
||||||
///// Newly Added Edge Vertex
|
///// Newly Added Edge Vertex
|
||||||
} else if (opposites && opposites.length === 2) {
|
} else if (opposites && opposites.length === 2) {
|
||||||
const k = opposites.length;
|
const k = opposites.length;
|
||||||
const beta = 0.125; /* 1/8 */
|
const beta = 0.125; /* 1/8 */
|
||||||
|
|
@ -734,93 +734,95 @@ class LoopSubdivision {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
///// Local Functions, Hash
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
const _positionShift = Math.pow(10, POSITION_DECIMALS);
|
/////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
///// Local Functions, Hash
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
/** Compares two numbers to see if they're almost the same */
|
const _positionShift = Math.pow(10, POSITION_DECIMALS);
|
||||||
function fuzzy(a, b, tolerance = 0.00001) {
|
|
||||||
return ((a < (b + tolerance)) && (a > (b - tolerance)));
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Generates hash strong from Number */
|
/** Compares two numbers to see if they're almost the same */
|
||||||
function hashFromNumber(num, shift = _positionShift) {
|
function fuzzy(a, b, tolerance = 0.00001) {
|
||||||
let roundedNumber = round(num * shift);
|
return ((a < (b + tolerance)) && (a > (b - tolerance)));
|
||||||
if (roundedNumber == 0) roundedNumber = 0; /* prevent -0 (signed 0 can effect Math.atan2(), etc.) */
|
|
||||||
return `${roundedNumber}`;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Generates hash strong from Vector3 */
|
|
||||||
function hashFromVector(vector, shift = _positionShift) {
|
|
||||||
return `${hashFromNumber(vector.x, shift)},${hashFromNumber(vector.y, shift)},${hashFromNumber(vector.z, shift)}`;
|
|
||||||
}
|
|
||||||
|
|
||||||
function round(x) {
|
|
||||||
return (x + ((x > 0) ? 0.5 : -0.5)) << 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
///// Local Functions, Geometry
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
function calcNormal(target, vec1, vec2, vec3) {
|
|
||||||
_temp.subVectors(vec1, vec2);
|
|
||||||
target.subVectors(vec2, vec3);
|
|
||||||
target.cross(_temp).normalize();
|
|
||||||
}
|
|
||||||
|
|
||||||
function gatherAttributes(geometry) {
|
|
||||||
const desired = [ 'position', 'normal', 'uv' ];
|
|
||||||
const contains = Object.keys(geometry.attributes);
|
|
||||||
const attributeList = Array.from(new Set(desired.concat(contains)));
|
|
||||||
return attributeList;
|
|
||||||
}
|
|
||||||
|
|
||||||
function setTriangle(positions, index, step, vec0, vec1, vec2) {
|
|
||||||
if (step >= 1) {
|
|
||||||
positions[index + 0 + (step * 0)] = vec0.x;
|
|
||||||
positions[index + 0 + (step * 1)] = vec1.x;
|
|
||||||
positions[index + 0 + (step * 2)] = vec2.x;
|
|
||||||
}
|
|
||||||
if (step >= 2) {
|
|
||||||
positions[index + 1 + (step * 0)] = vec0.y;
|
|
||||||
positions[index + 1 + (step * 1)] = vec1.y;
|
|
||||||
positions[index + 1 + (step * 2)] = vec2.y;
|
|
||||||
}
|
|
||||||
if (step >= 3) {
|
|
||||||
positions[index + 2 + (step * 0)] = vec0.z;
|
|
||||||
positions[index + 2 + (step * 1)] = vec1.z;
|
|
||||||
positions[index + 2 + (step * 2)] = vec2.z;
|
|
||||||
}
|
|
||||||
if (step >= 4) {
|
|
||||||
positions[index + 3 + (step * 0)] = vec0.w;
|
|
||||||
positions[index + 3 + (step * 1)] = vec1.w;
|
|
||||||
positions[index + 3 + (step * 2)] = vec2.w;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function verifyGeometry(geometry) {
|
|
||||||
if (geometry === undefined) {
|
|
||||||
console.warn(`LoopSubdivision: Geometry provided is undefined`);
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (! geometry.isBufferGeometry) {
|
/** Generates hash strong from Number */
|
||||||
console.warn(`LoopSubdivision: Geometry provided is not 'BufferGeometry' type`);
|
function hashFromNumber(num, shift = _positionShift) {
|
||||||
return false;
|
let roundedNumber = round(num * shift);
|
||||||
|
if (roundedNumber == 0) roundedNumber = 0; /* prevent -0 (signed 0 can effect Math.atan2(), etc.) */
|
||||||
|
return `${roundedNumber}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (geometry.attributes.position === undefined) {
|
/** Generates hash strong from Vector3 */
|
||||||
console.warn(`LoopSubdivision: Geometry provided missing required 'position' attribute`);
|
function hashFromVector(vector, shift = _positionShift) {
|
||||||
return false;
|
return `${hashFromNumber(vector.x, shift)},${hashFromNumber(vector.y, shift)},${hashFromNumber(vector.z, shift)}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (geometry.attributes.normal === undefined) {
|
function round(x) {
|
||||||
geometry.computeVertexNormals();
|
return (x + ((x > 0) ? 0.5 : -0.5)) << 0;
|
||||||
}
|
}
|
||||||
return true;
|
|
||||||
}
|
/////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
///// Local Functions, Geometry
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
function calcNormal(target, vec1, vec2, vec3) {
|
||||||
|
_temp.subVectors(vec1, vec2);
|
||||||
|
target.subVectors(vec2, vec3);
|
||||||
|
target.cross(_temp).normalize();
|
||||||
|
}
|
||||||
|
|
||||||
|
function gatherAttributes(geometry) {
|
||||||
|
const desired = ['position', 'normal', 'uv'];
|
||||||
|
const contains = Object.keys(geometry.attributes);
|
||||||
|
const attributeList = Array.from(new Set(desired.concat(contains)));
|
||||||
|
return attributeList;
|
||||||
|
}
|
||||||
|
|
||||||
|
function setTriangle(positions, index, step, vec0, vec1, vec2) {
|
||||||
|
if (step >= 1) {
|
||||||
|
positions[index + 0 + (step * 0)] = vec0.x;
|
||||||
|
positions[index + 0 + (step * 1)] = vec1.x;
|
||||||
|
positions[index + 0 + (step * 2)] = vec2.x;
|
||||||
|
}
|
||||||
|
if (step >= 2) {
|
||||||
|
positions[index + 1 + (step * 0)] = vec0.y;
|
||||||
|
positions[index + 1 + (step * 1)] = vec1.y;
|
||||||
|
positions[index + 1 + (step * 2)] = vec2.y;
|
||||||
|
}
|
||||||
|
if (step >= 3) {
|
||||||
|
positions[index + 2 + (step * 0)] = vec0.z;
|
||||||
|
positions[index + 2 + (step * 1)] = vec1.z;
|
||||||
|
positions[index + 2 + (step * 2)] = vec2.z;
|
||||||
|
}
|
||||||
|
if (step >= 4) {
|
||||||
|
positions[index + 3 + (step * 0)] = vec0.w;
|
||||||
|
positions[index + 3 + (step * 1)] = vec1.w;
|
||||||
|
positions[index + 3 + (step * 2)] = vec2.w;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function verifyGeometry(geometry) {
|
||||||
|
if (geometry === undefined) {
|
||||||
|
console.warn(`LoopSubdivision: Geometry provided is undefined`);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!geometry.isBufferGeometry) {
|
||||||
|
console.warn(`LoopSubdivision: Geometry provided is not 'BufferGeometry' type`);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (geometry.attributes.position === undefined) {
|
||||||
|
console.warn(`LoopSubdivision: Geometry provided missing required 'position' attribute`);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (geometry.attributes.normal === undefined) {
|
||||||
|
geometry.computeVertexNormals();
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
})()
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ window.ThreeD = (function () {
|
||||||
scale: 50,
|
scale: 50,
|
||||||
lightness: 0.7,
|
lightness: 0.7,
|
||||||
shadow: 0.5,
|
shadow: 0.5,
|
||||||
sun: {x: 300, y: 1500, z: 800},
|
sun: {x: 100, y: 600, z: 1000},
|
||||||
rotateMesh: 0,
|
rotateMesh: 0,
|
||||||
rotateGlobe: 0.5,
|
rotateGlobe: 0.5,
|
||||||
skyColor: "#9ecef5",
|
skyColor: "#9ecef5",
|
||||||
|
|
@ -15,7 +15,8 @@ window.ThreeD = (function () {
|
||||||
wireframe: 0,
|
wireframe: 0,
|
||||||
resolution: 2,
|
resolution: 2,
|
||||||
resolutionScale: 3,
|
resolutionScale: 3,
|
||||||
sunColor: "#ffffff"
|
sunColor: "#cccccc",
|
||||||
|
subdivide: 0
|
||||||
};
|
};
|
||||||
|
|
||||||
// set variables
|
// set variables
|
||||||
|
|
@ -95,7 +96,11 @@ window.ThreeD = (function () {
|
||||||
|
|
||||||
const setScale = function (scale) {
|
const setScale = function (scale) {
|
||||||
options.scale = scale;
|
options.scale = scale;
|
||||||
geometry.vertices.forEach((v, i) => (v.z = getMeshHeight(i)));
|
let vertices = geometry.getAttribute('position');
|
||||||
|
for(let i = 0; i < vertices.count; i++){
|
||||||
|
vertices.setZ(i,getMeshHeight(i));
|
||||||
|
}
|
||||||
|
geometry.setAttribute('position',vertices);
|
||||||
geometry.verticesNeedUpdate = true;
|
geometry.verticesNeedUpdate = true;
|
||||||
geometry.computeVertexNormals();
|
geometry.computeVertexNormals();
|
||||||
geometry.verticesNeedUpdate = false;
|
geometry.verticesNeedUpdate = false;
|
||||||
|
|
@ -163,6 +168,12 @@ window.ThreeD = (function () {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const toggle3dSubdivision = function(){
|
||||||
|
console.log("toggle 3d subdivision");
|
||||||
|
options.subdivide = !options.subdivide;
|
||||||
|
redraw();
|
||||||
|
}
|
||||||
|
|
||||||
const toggleWireframe = function () {
|
const toggleWireframe = function () {
|
||||||
options.wireframe = !options.wireframe;
|
options.wireframe = !options.wireframe;
|
||||||
redraw();
|
redraw();
|
||||||
|
|
@ -222,7 +233,7 @@ window.ThreeD = (function () {
|
||||||
Renderer = new THREE.WebGLRenderer({canvas, antialias: true, preserveDrawingBuffer: true});
|
Renderer = new THREE.WebGLRenderer({canvas, antialias: true, preserveDrawingBuffer: true});
|
||||||
Renderer.setSize(canvas.width, canvas.height);
|
Renderer.setSize(canvas.width, canvas.height);
|
||||||
Renderer.shadowMap.enabled = true;
|
Renderer.shadowMap.enabled = true;
|
||||||
Renderer.shadowMap.type = THREE.PCFSoftShadowMap;
|
// Renderer.shadowMap.type = THREE.PCFSoftShadowMap;
|
||||||
if (options.extendedWater) extendWater(graphWidth, graphHeight);
|
if (options.extendedWater) extendWater(graphWidth, graphHeight);
|
||||||
createMesh(graphWidth, graphHeight, grid.cellsX, grid.cellsY);
|
createMesh(graphWidth, graphHeight, grid.cellsX, grid.cellsY);
|
||||||
|
|
||||||
|
|
@ -480,9 +491,8 @@ window.ThreeD = (function () {
|
||||||
material = new THREE.MeshLambertMaterial();
|
material = new THREE.MeshLambertMaterial();
|
||||||
material.wireframe = true;
|
material.wireframe = true;
|
||||||
}else{
|
}else{
|
||||||
material = new THREE.MeshStandardMaterial();
|
material = new THREE.MeshLambertMaterial();
|
||||||
material.map = texture;
|
material.map = texture;
|
||||||
material.roughness = 0.9;
|
|
||||||
material.transparent = true;
|
material.transparent = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -493,14 +503,24 @@ window.ThreeD = (function () {
|
||||||
for(let i = 0; i < vertices.count; i++){
|
for(let i = 0; i < vertices.count; i++){
|
||||||
vertices.setZ(i,getMeshHeight(i));
|
vertices.setZ(i,getMeshHeight(i));
|
||||||
}
|
}
|
||||||
// vertices.forEach((v, i) => (v.z = getMeshHeight(i)));
|
|
||||||
geometry.setAttribute('position',vertices);
|
geometry.setAttribute('position',vertices);
|
||||||
geometry.computeVertexNormals();
|
geometry.computeVertexNormals();
|
||||||
|
|
||||||
//This takes too long
|
//This takes too long
|
||||||
const smoothGeometry = LoopSubdivision.modify(geometry,1,undefined);
|
|
||||||
if (mesh) scene.remove(mesh);
|
if (mesh) scene.remove(mesh);
|
||||||
mesh = new THREE.Mesh(smoothGeometry, material);
|
if(options.subdivide){
|
||||||
|
const subdivideParams = {
|
||||||
|
split: true,
|
||||||
|
uvSmooth: false,
|
||||||
|
preserveEdges: true,
|
||||||
|
flatOnly: false,
|
||||||
|
maxTriangles: Infinity
|
||||||
|
};
|
||||||
|
const smoothGeometry = loopSubdivision.modify(geometry,1,subdivideParams);
|
||||||
|
mesh = new THREE.Mesh(smoothGeometry, material);
|
||||||
|
}else{
|
||||||
|
mesh = new THREE.Mesh(geometry, material);
|
||||||
|
}
|
||||||
mesh.rotation.x = -Math.PI / 2;
|
mesh.rotation.x = -Math.PI / 2;
|
||||||
mesh.castShadow = true;
|
mesh.castShadow = true;
|
||||||
mesh.receiveShadow = true;
|
mesh.receiveShadow = true;
|
||||||
|
|
@ -704,6 +724,7 @@ window.ThreeD = (function () {
|
||||||
setSun,
|
setSun,
|
||||||
setRotation,
|
setRotation,
|
||||||
toggleLabels,
|
toggleLabels,
|
||||||
|
toggle3dSubdivision,
|
||||||
toggleWireframe,
|
toggleWireframe,
|
||||||
toggleSky,
|
toggleSky,
|
||||||
setResolution,
|
setResolution,
|
||||||
|
|
|
||||||
|
|
@ -1070,8 +1070,9 @@ function toggle3dOptions() {
|
||||||
document.getElementById("options3dMeshSky").addEventListener("input", changeColors);
|
document.getElementById("options3dMeshSky").addEventListener("input", changeColors);
|
||||||
document.getElementById("options3dMeshWater").addEventListener("input", changeColors);
|
document.getElementById("options3dMeshWater").addEventListener("input", changeColors);
|
||||||
document.getElementById("options3dGlobeResolution").addEventListener("change", changeResolution);
|
document.getElementById("options3dGlobeResolution").addEventListener("change", changeResolution);
|
||||||
document.getElementById("options3dMeshWireframeMode").addEventListener("change",toggleWireframe3d);
|
// document.getElementById("options3dMeshWireframeMode").addEventListener("change",toggleWireframe3d);
|
||||||
document.getElementById("options3dSunColor").addEventListener("input", changeSunColor);
|
document.getElementById("options3dSunColor").addEventListener("input", changeSunColor);
|
||||||
|
document.getElementById("options3dSubdivide").addEventListener("change",toggle3dSubdivision);
|
||||||
|
|
||||||
|
|
||||||
function updateValues() {
|
function updateValues() {
|
||||||
|
|
@ -1094,6 +1095,7 @@ function toggle3dOptions() {
|
||||||
options3dMeshWater.value = ThreeD.options.waterColor;
|
options3dMeshWater.value = ThreeD.options.waterColor;
|
||||||
options3dGlobeResolution.value = ThreeD.options.resolution;
|
options3dGlobeResolution.value = ThreeD.options.resolution;
|
||||||
options3dSunColor.value = ThreeD.options.sunColor;
|
options3dSunColor.value = ThreeD.options.sunColor;
|
||||||
|
options3dSubdivide.value = ThreeD.options.subdivide;
|
||||||
console.log("options3dSunColor.value =",ThreeD.options.sunColor);
|
console.log("options3dSunColor.value =",ThreeD.options.sunColor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1134,10 +1136,15 @@ function toggle3dOptions() {
|
||||||
ThreeD.toggleLabels();
|
ThreeD.toggleLabels();
|
||||||
}
|
}
|
||||||
|
|
||||||
function toggleWireframe3d() {
|
function toggle3dSubdivision(){
|
||||||
ThreeD.toggleWireframe();
|
console.log(options.subdivide);
|
||||||
|
ThreeD.toggle3dSubdivision();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// function toggleWireframe3d() {
|
||||||
|
// ThreeD.toggleWireframe();
|
||||||
|
// }
|
||||||
|
|
||||||
function toggleSkyMode() {
|
function toggleSkyMode() {
|
||||||
const hide = ThreeD.options.extendedWater;
|
const hide = ThreeD.options.extendedWater;
|
||||||
options3dColorSection.style.display = hide ? "none" : "block";
|
options3dColorSection.style.display = hide ? "none" : "block";
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
// version and caching control
|
// version and caching control
|
||||||
const version = "1.89.34"; // generator version, update each time
|
const version = "1.89.35"; // generator version, update each time
|
||||||
|
|
||||||
{
|
{
|
||||||
document.title += " v" + version;
|
document.title += " v" + version;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue