mirror of
https://github.com/Azgaar/Fantasy-Map-Generator.git
synced 2025-12-16 17:31:24 +01:00
Added OBJ exporter for 3D. (#609)
* Added OBJ exporter * Don't add links to document body * Changed to use downloadFile function
This commit is contained in:
parent
547069f25c
commit
a27e592dcb
5 changed files with 36 additions and 4 deletions
|
|
@ -287,3 +287,4 @@
|
|||
.icon-button-ambush:before {content:'🌳'; padding-right: .4em;}
|
||||
.icon-button-landing:before {content:'⚓'; padding-right: .4em;}
|
||||
.icon-button-air:before {content:'💨'; padding-right: .4em;}
|
||||
.icon-button-screenshot:before {content:'🖥️'; padding-right: .4em;}
|
||||
|
|
|
|||
|
|
@ -3358,7 +3358,8 @@
|
|||
<div id="options3dBottom" style="margin-top: .2em">
|
||||
<button id="options3dUpdate" data-tip="Update the scene" class="icon-cw"></button>
|
||||
<button data-tip="Configure world and map size and climate settings" onclick="editWorld()" class="icon-globe"></button>
|
||||
<button id="options3dSave" data-tip="Save screenshot of the 3d scene" class="icon-download"></button>
|
||||
<button id="options3dSave" data-tip="Save screenshot of the 3d scene" class="icon-button-screenshot"></button>
|
||||
<button id="options3dOBJSave" data-tip="Save OBJ file of the 3d scene" class="icon-download"></button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
|
|||
5
libs/objexporter.min.js
vendored
Normal file
5
libs/objexporter.min.js
vendored
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
THREE.OBJExporter=function(){};
|
||||
THREE.OBJExporter.prototype={constructor:THREE.OBJExporter,parse:function(A){var f="",n=0,w=0,x=0,g=new THREE.Vector3,p=new THREE.Vector3,u=new THREE.Vector2,a,b,y,c,k,v=[];A.traverse(function(e){if(e instanceof THREE.Mesh){var r=0,t=0,d=0,h=e.geometry,z=new THREE.Matrix3;h instanceof THREE.Geometry&&(h=(new THREE.BufferGeometry).setFromObject(e));if(h instanceof THREE.BufferGeometry){var q=h.getAttribute("position"),l=h.getAttribute("normal"),m=h.getAttribute("uv");h=h.getIndex();f+="o "+e.name+
|
||||
"\n";e.material&&e.material.name&&(f+="usemtl "+e.material.name+"\n");if(void 0!==q)for(a=0,c=q.count;a<c;a++,r++)g.x=q.getX(a),g.y=q.getY(a),g.z=q.getZ(a),g.applyMatrix4(e.matrixWorld),f+="v "+g.x+" "+g.y+" "+g.z+"\n";if(void 0!==m)for(a=0,c=m.count;a<c;a++,d++)u.x=m.getX(a),u.y=m.getY(a),f+="vt "+u.x+" "+u.y+"\n";if(void 0!==l)for(z.getNormalMatrix(e.matrixWorld),a=0,c=l.count;a<c;a++,t++)p.x=l.getX(a),p.y=l.getY(a),p.z=l.getZ(a),p.applyMatrix3(z).normalize(),f+="vn "+p.x+" "+p.y+" "+p.z+"\n";if(null!==
|
||||
h)for(a=0,c=h.count;a<c;a+=3){for(k=0;3>k;k++)b=h.getX(a+k)+1,v[k]=n+b+(l||m?"/"+(m?w+b:"")+(l?"/"+(x+b):""):"");f+="f "+v.join(" ")+"\n"}else for(a=0,c=q.count;a<c;a+=3){for(k=0;3>k;k++)b=a+k+1,v[k]=n+b+(l||m?"/"+(m?w+b:"")+(l?"/"+(x+b):""):"");f+="f "+v.join(" ")+"\n"}}else console.warn("THREE.OBJExporter.parseMesh(): geometry type unsupported",h);n+=r;w+=d;x+=t}if(e instanceof THREE.Line){r=0;d=e.geometry;t=e.type;d instanceof THREE.Geometry&&(d=(new THREE.BufferGeometry).setFromObject(e));if(d instanceof
|
||||
THREE.BufferGeometry){d=d.getAttribute("position");f+="o "+e.name+"\n";if(void 0!==d)for(a=0,c=d.count;a<c;a++,r++)g.x=d.getX(a),g.y=d.getY(a),g.z=d.getZ(a),g.applyMatrix4(e.matrixWorld),f+="v "+g.x+" "+g.y+" "+g.z+"\n";if("Line"===t){f+="l ";b=1;for(c=d.count;b<=c;b++)f+=n+b+" ";f+="\n"}if("LineSegments"===t)for(b=1,y=b+1,c=d.count;b<c;b+=2,y=b+1)f+="l "+(n+b)+" "+(n+y)+"\n"}else console.warn("THREE.OBJExporter.parseLine(): geometry type unsupported",d);n+=r}});return f}};
|
||||
|
|
@ -10,7 +10,8 @@ const options = {scale: 50, lightness: .7, shadow: .5, sun: {x: 100, y: 600, z:
|
|||
|
||||
// set variables
|
||||
let Renderer, scene, camera, controls, animationFrame, material, texture,
|
||||
geometry, mesh, ambientLight, spotLight, waterPlane, waterMaterial, waterMesh;
|
||||
geometry, mesh, ambientLight, spotLight, waterPlane, waterMaterial, waterMesh,
|
||||
objexporter;
|
||||
|
||||
// initiate 3d scene
|
||||
const create = async function(canvas, type = "viewMesh") {
|
||||
|
|
@ -126,6 +127,10 @@ const saveScreenshot = async function() {
|
|||
window.setTimeout(() => window.URL.revokeObjectURL(URL), 5000);
|
||||
}
|
||||
|
||||
const saveOBJ = async function() {
|
||||
downloadFile(await getOBJ(), getFileName() + ".obj", "text/plain;charset=UTF-8");
|
||||
}
|
||||
|
||||
// start 3d view and heightmap edit preview
|
||||
async function newMesh(canvas) {
|
||||
const loaded = await loadTHREE();
|
||||
|
|
@ -289,6 +294,13 @@ async function updateGlobeTexure(addMesh) {
|
|||
img2.src = await getMapURL("mesh", "globe");;
|
||||
}
|
||||
|
||||
async function getOBJ() {
|
||||
objexporter = await OBJExporter();
|
||||
|
||||
const data = await objexporter.parse(mesh);
|
||||
return data;
|
||||
}
|
||||
|
||||
function addGlobe3dMesh() {
|
||||
geometry = new THREE.SphereBufferGeometry(1, 64, 64);
|
||||
mesh = new THREE.Mesh(geometry, material);
|
||||
|
|
@ -332,6 +344,18 @@ function OrbitControls(camera, domElement) {
|
|||
});
|
||||
}
|
||||
|
||||
return {create, redraw, update, stop, options, setScale, setLightness, setSun, setRotation, toggleSky, setResolution, setColors, saveScreenshot};
|
||||
function OBJExporter() {
|
||||
if (THREE.OBJExporter) return new THREE.OBJExporter();
|
||||
|
||||
return new Promise(resolve => {
|
||||
const script = document.createElement('script');
|
||||
script.src = "libs/objexporter.min.js"
|
||||
document.head.append(script);
|
||||
script.onload = () => resolve(new THREE.OBJExporter());
|
||||
script.onerror = () => resolve(false);
|
||||
});
|
||||
}
|
||||
|
||||
return {create, redraw, update, stop, options, setScale, setLightness, setSun, setRotation, toggleSky, setResolution, setColors, saveScreenshot, saveOBJ};
|
||||
|
||||
})));
|
||||
|
|
|
|||
|
|
@ -707,6 +707,7 @@ function toggle3dOptions() {
|
|||
|
||||
document.getElementById("options3dUpdate").addEventListener("click", ThreeD.update);
|
||||
document.getElementById("options3dSave").addEventListener("click", ThreeD.saveScreenshot);
|
||||
document.getElementById("options3dOBJSave").addEventListener("click", ThreeD.saveOBJ);
|
||||
|
||||
document.getElementById("options3dScaleRange").addEventListener("input", changeHeightScale);
|
||||
document.getElementById("options3dScaleNumber").addEventListener("change", changeHeightScale);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue