mirror of
https://github.com/Doodle3D/Doodle3D-Slicer.git
synced 2024-12-23 11:33:49 +01:00
improved gcode handling
This commit is contained in:
parent
38bf3c74f3
commit
17bd8f4f25
@ -37,7 +37,7 @@ function init () {
|
||||
|
||||
var loader = new THREE.STLLoader();
|
||||
loader.load("models/dom.stl", function (geometry) {
|
||||
var geometry = new THREE.BoxGeometry(10, 10, 10, 1, 1, 1);
|
||||
//var geometry = new THREE.BoxGeometry(10, 10, 10, 1, 1, 1);
|
||||
//var geometry = new THREE.SphereGeometry(10, 20, 10);
|
||||
//var geometry = new THREE.TorusGeometry(20, 10, 30, 30);
|
||||
/*
|
||||
|
102
src/gcode.js
102
src/gcode.js
@ -9,12 +9,32 @@
|
||||
D3D.GCode = function () {
|
||||
"use strict";
|
||||
|
||||
this.current = {};
|
||||
|
||||
this.extruder = 0.0;
|
||||
this.bottom = true;
|
||||
this.isRetracted = false;
|
||||
this.isFanOn = false;
|
||||
this.gcode = [];
|
||||
this.nozzlePosition = new THREE.Vector2(0, 0);
|
||||
};
|
||||
D3D.GCode.prototype.addGCode = function (command) {
|
||||
"use strict";
|
||||
|
||||
var str = [];
|
||||
|
||||
for (var i in command) {
|
||||
if (this.current[i] !== command[i] || i === "G") {
|
||||
str.push(i + command[i]);
|
||||
this.current[i] = command[i];
|
||||
}
|
||||
}
|
||||
|
||||
str = str.join(" ");
|
||||
if (str.length > 0) {
|
||||
this.gcode.push(str);
|
||||
}
|
||||
};
|
||||
D3D.GCode.prototype.setSettings = function (printer) {
|
||||
"use strict";
|
||||
|
||||
@ -22,10 +42,33 @@ D3D.GCode.prototype.setSettings = function (printer) {
|
||||
|
||||
return this;
|
||||
};
|
||||
D3D.GCode.prototype.turnOnFan = function () {
|
||||
D3D.GCode.prototype.turnFanOn = function (fanSpeed) {
|
||||
"use strict";
|
||||
|
||||
this.gcode.push("M106");
|
||||
this.isFanOn = true;
|
||||
|
||||
var gcode = {
|
||||
"M": 106
|
||||
};
|
||||
|
||||
if (fanSpeed !== undefined) {
|
||||
gcode["S"] = fanSpeed;
|
||||
}
|
||||
|
||||
this.addGCode(gcode);
|
||||
|
||||
return this;
|
||||
};
|
||||
D3D.GCode.prototype.turnFanOff = function () {
|
||||
"use strict";
|
||||
|
||||
this.isFanOn = false;
|
||||
|
||||
this.addGCode({
|
||||
"M": 107
|
||||
});
|
||||
|
||||
return this;
|
||||
};
|
||||
D3D.GCode.prototype.moveTo = function (extrude, x, y, layer) {
|
||||
"use strict";
|
||||
@ -58,30 +101,27 @@ D3D.GCode.prototype.moveTo = function (extrude, x, y, layer) {
|
||||
var filamentSurfaceArea = Math.pow((filamentThickness/2), 2) * Math.PI;
|
||||
this.extruder += lineLength * nozzleDiameter * layerHeight / filamentSurfaceArea * flowRate;
|
||||
|
||||
this.gcode.push(
|
||||
"G1" +
|
||||
" X" + x.toFixed(3) +
|
||||
" Y" + y.toFixed(3) +
|
||||
((z !== this.lastZ) ? (" Z" + z.toFixed(3)) : "") +
|
||||
((speed !== this.lastSpeed) ? (" F" + speed.toFixed(3)) : "") +
|
||||
" E" + this.extruder.toFixed(3)
|
||||
);
|
||||
this.addGCode({
|
||||
"G": 1,
|
||||
"X": x.toFixed(3), "Y": y.toFixed(3), "Z": z.toFixed(3),
|
||||
"F": speed.toFixed(3),
|
||||
"E": this.extruder.toFixed(3)
|
||||
});
|
||||
}
|
||||
else {
|
||||
var speed = travelSpeed * 60;
|
||||
|
||||
this.gcode.push(
|
||||
"G0" +
|
||||
" X" + x.toFixed(3) + " Y" + y.toFixed(3) + " Z" + z +
|
||||
" F" + speed.toFixed(3)
|
||||
);
|
||||
this.addGCode.({
|
||||
"G": 0,
|
||||
"X": x.toFixed(3), "Y": y.toFixed(3), "Z": z.toFixed(3),
|
||||
"F": speed.toFixed(3)
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
this.lastSpeed = speed;
|
||||
this.lastZ = z;
|
||||
|
||||
this.nozzlePosition = new THREE.Vector2(x, y);
|
||||
|
||||
return this;
|
||||
};
|
||||
D3D.GCode.prototype.unRetract = function () {
|
||||
"use strict";
|
||||
@ -96,12 +136,14 @@ D3D.GCode.prototype.unRetract = function () {
|
||||
var speed = retractionSpeed * 60;
|
||||
|
||||
if (this.extruder > retractionMinDistance && retractionEnabled) {
|
||||
this.gcode.push(
|
||||
"G0" +
|
||||
" E" + this.extruder.toFixed(3) +
|
||||
" F" + (speed * 60).toFixed(3)
|
||||
);
|
||||
this.addGCode({
|
||||
"G": 0,
|
||||
"E": this.extruder.toFixed(3),
|
||||
"F": speed.toFixed(3)
|
||||
});
|
||||
}
|
||||
|
||||
return this;
|
||||
};
|
||||
D3D.GCode.prototype.retract = function () {
|
||||
"use strict";
|
||||
@ -116,16 +158,16 @@ D3D.GCode.prototype.retract = function () {
|
||||
var speed = retractionSpeed * 60;
|
||||
|
||||
if (this.extruder > retractionMinDistance && retractionEnabled) {
|
||||
this.gcode.push(
|
||||
"G0" +
|
||||
" E" + (this.extruder - retractionAmount).toFixed(3) +
|
||||
" F" + speed.toFixed(3)
|
||||
);
|
||||
this.addGCode({
|
||||
"G": 0,
|
||||
"E": (this.extruder - retractionAmount).toFixed(3),
|
||||
"F": speed.toFixed(3)
|
||||
});
|
||||
}
|
||||
|
||||
this.lastSpeed = speed;
|
||||
return this;
|
||||
};
|
||||
D3D.GCode.prototype.getFinal = function () {
|
||||
D3D.GCode.prototype.getGCode = function () {
|
||||
"use strict";
|
||||
|
||||
return this.settings.getStartCode().concat(this.gcode, this.settings.getEndCode());
|
||||
|
@ -24,26 +24,23 @@ D3D.Slicer.prototype.setMesh = function (geometry, matrix) {
|
||||
geometry = new THREE.Geometry().fromBufferGeometry(geometry);
|
||||
}
|
||||
|
||||
//remove duplicate vertices;
|
||||
//apply mesh matrix on geometry;
|
||||
geometry.applyMatrix(matrix);
|
||||
geometry.mergeVertices();
|
||||
geometry.computeFaceNormals();
|
||||
geometry.computeBoundingBox();
|
||||
|
||||
/*
|
||||
for (var i = 0; i < geometry.vertices.length; i ++) {
|
||||
var vertexA = geometry.vertices[i];
|
||||
for (var i = 0; i < geometry.faces.length; i ++) {
|
||||
var face = geometry.faces[i];
|
||||
var normal = face.normal;
|
||||
|
||||
for (var j = i + 1; j < geometry.vertices.length; j ++) {
|
||||
var vertexB = geometry.vertices[j];
|
||||
|
||||
if (vertexA.equals(vertexB)) {
|
||||
geometry.vertices[j] = vertexA;
|
||||
}
|
||||
if (normal.x === 0 && normal.y === 0 && normal.z === 0) {
|
||||
geometry.faces.splice(i, 1);
|
||||
i --;
|
||||
}
|
||||
}
|
||||
*/
|
||||
geometry.mergeVertices();
|
||||
|
||||
//apply mesh matrix on geometry;
|
||||
geometry.applyMatrix(matrix);
|
||||
geometry.computeFaceNormals();
|
||||
geometry.computeBoundingBox();
|
||||
|
||||
this.geometry = geometry;
|
||||
|
||||
@ -77,9 +74,7 @@ D3D.Slicer.prototype.createLines = function () {
|
||||
|
||||
var self = this;
|
||||
function addLine (a, b) {
|
||||
|
||||
//think lookup can only be b_a, a_b is only possible when face is flipped
|
||||
var index = lineLookup[b + "_" + a] || lineLookup[a + "_" + b];
|
||||
var index = lineLookup[b + "_" + a];
|
||||
|
||||
if (index === undefined) {
|
||||
index = self.lines.length;
|
||||
@ -123,6 +118,7 @@ D3D.Slicer.prototype.createLines = function () {
|
||||
};
|
||||
D3D.Slicer.prototype.slice = function (layerHeight, height) {
|
||||
"use strict";
|
||||
var numLayers = height / layerHeight;
|
||||
|
||||
var layersIntersections = [];
|
||||
|
||||
@ -133,7 +129,7 @@ D3D.Slicer.prototype.slice = function (layerHeight, height) {
|
||||
var max = Math.floor(Math.max(line.start.y, line.end.y) / layerHeight);
|
||||
|
||||
for (var layerIndex = min; layerIndex <= max; layerIndex ++) {
|
||||
if (layerIndex >= 0 && layerIndex < height / layerHeight) {
|
||||
if (layerIndex >= 0 && layerIndex < numLayers) {
|
||||
if (layersIntersections[layerIndex] === undefined) {
|
||||
layersIntersections[layerIndex] = [];
|
||||
}
|
||||
@ -151,6 +147,7 @@ D3D.Slicer.prototype.slice = function (layerHeight, height) {
|
||||
var y = layer * layerHeight;
|
||||
|
||||
var intersections = [];
|
||||
var log = [];
|
||||
for (var i = 0; i < layerIntersections.length; i ++) {
|
||||
var index = layerIntersections[i];
|
||||
var line = this.lines[index].line;
|
||||
@ -164,8 +161,14 @@ D3D.Slicer.prototype.slice = function (layerHeight, height) {
|
||||
var x = line.end.x * alpha + line.start.x * (1 - alpha);
|
||||
var z = line.end.z * alpha + line.start.z * (1 - alpha);
|
||||
}
|
||||
|
||||
intersections[index] = new THREE.Vector2(z, x);
|
||||
log.push({x: z, y: x, index: index, connects: this.lines[index].connects});
|
||||
}
|
||||
/*if (layer === 10) {
|
||||
console.log(JSON.stringify(log));
|
||||
breakCode();
|
||||
}*/
|
||||
|
||||
var done = [];
|
||||
var slice = [];
|
||||
@ -179,24 +182,33 @@ D3D.Slicer.prototype.slice = function (layerHeight, height) {
|
||||
var intersection = intersections[index];
|
||||
shape.push({X: intersection.x, Y: intersection.y});
|
||||
|
||||
done.push(index);
|
||||
|
||||
var connects = this.lines[index].connects;
|
||||
var faceNormals = this.lines[index].normals;
|
||||
for (var j = 0; j < connects.length; j ++) {
|
||||
index = connects[j];
|
||||
|
||||
if (intersections[index] && done.indexOf(index) === -1) {
|
||||
if (intersections[index] !== undefined && done.indexOf(index) === -1) {
|
||||
done.push(index);
|
||||
|
||||
var a = new THREE.Vector2(intersection.x, intersection.y);
|
||||
var b = intersections[index];
|
||||
var normal = a.sub(b).normal().normalize();
|
||||
var faceNormal = faceNormals[Math.floor(j/2)];
|
||||
|
||||
if (normal.dot(faceNormal) > 0) {
|
||||
break;
|
||||
if (a.distanceTo(b) === 0) {
|
||||
connects = connects.concat(this.lines[index].connects);
|
||||
faceNormals = faceNormals.concat(this.lines[index].normals);
|
||||
index = -1;
|
||||
}
|
||||
else {
|
||||
index = -1;
|
||||
var normal = a.sub(b).normal().normalize();
|
||||
var faceNormal = faceNormals[Math.floor(j/2)];
|
||||
|
||||
if (normal.dot(faceNormal) >= 0) {
|
||||
//if (true) {
|
||||
break;
|
||||
}
|
||||
else {
|
||||
index = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
@ -234,6 +246,7 @@ D3D.Slicer.prototype.slice = function (layerHeight, height) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
var layerParts = [];
|
||||
|
||||
for (var i = 0; i < slice.length; i ++) {
|
||||
@ -265,7 +278,6 @@ D3D.Slicer.prototype.slice = function (layerHeight, height) {
|
||||
this.progress.sliceLayer = layer;
|
||||
this.updateProgress();
|
||||
}
|
||||
|
||||
return slices;
|
||||
};
|
||||
D3D.Slicer.prototype.slicesToData = function (slices, printer) {
|
||||
@ -405,7 +417,7 @@ D3D.Slicer.prototype.getFillTemplate = function (bounds, size, even, uneven) {
|
||||
return paths;
|
||||
};
|
||||
/*
|
||||
D3D.Slicer.prototype.dataToGcode = function (data, printer) {
|
||||
D3D.Slicer.prototype.dataToGCode = function (data, printer) {
|
||||
"use strict";
|
||||
|
||||
var layerHeight = printer.config["printer.layerHeight"];
|
||||
@ -423,7 +435,7 @@ D3D.Slicer.prototype.dataToGcode = function (data, printer) {
|
||||
var retractionMinDistance = printer.config["printer.retraction.minDistance"];
|
||||
var retractionAmount = printer.config["printer.retraction.amount"];
|
||||
|
||||
function sliceToGcode (path) {
|
||||
function sliceToGCode (path) {
|
||||
var gcode = [];
|
||||
|
||||
for (var i = 0; i < path.length; i ++) {
|
||||
@ -507,9 +519,9 @@ D3D.Slicer.prototype.dataToGcode = function (data, printer) {
|
||||
for (var i = 0; i < slice.length; i ++) {
|
||||
var layerPart = slice[i];
|
||||
|
||||
gcode = gcode.concat(sliceToGcode(layerPart.outerLayer));
|
||||
gcode = gcode.concat(sliceToGcode(layerPart.insets));
|
||||
gcode = gcode.concat(sliceToGcode(layerPart.fill));
|
||||
gcode = gcode.concat(sliceToGCode(layerPart.outerLayer));
|
||||
gcode = gcode.concat(sliceToGCode(layerPart.insets));
|
||||
gcode = gcode.concat(sliceToGCode(layerPart.fill));
|
||||
}
|
||||
|
||||
this.progress.gcodeLayer = layer;
|
||||
@ -521,12 +533,12 @@ D3D.Slicer.prototype.dataToGcode = function (data, printer) {
|
||||
return gcode;
|
||||
};
|
||||
*/
|
||||
D3D.Slicer.prototype.dataToGcode = function (data, printer) {
|
||||
D3D.Slicer.prototype.dataToGCode = function (data, printer) {
|
||||
"use strict";
|
||||
|
||||
var gcode = new D3D.GCode().setSettings(printer);
|
||||
|
||||
function sliceToGcode (path, retract, unRetract) {
|
||||
function sliceToGCode (path, retract, unRetract) {
|
||||
for (var i = 0; i < path.length; i ++) {
|
||||
var shape = path[i];
|
||||
|
||||
@ -557,25 +569,25 @@ D3D.Slicer.prototype.dataToGcode = function (data, printer) {
|
||||
var slice = data[layer];
|
||||
|
||||
if (layer === 1) {
|
||||
gcode.turnOnFan();
|
||||
gcode.turnFanOn();
|
||||
gcode.bottom = false;
|
||||
}
|
||||
|
||||
for (var i = 0; i < slice.length; i ++) {
|
||||
var layerPart = slice[i];
|
||||
|
||||
sliceToGcode(layerPart.outerLayer, false, true);
|
||||
sliceToGcode(layerPart.insets, false, false);
|
||||
sliceToGcode(layerPart.fill, true, false);
|
||||
sliceToGCode(layerPart.outerLayer, false, true);
|
||||
sliceToGCode(layerPart.insets, false, false);
|
||||
sliceToGCode(layerPart.fill, true, false);
|
||||
}
|
||||
|
||||
this.progress.gcodeLayer = layer;
|
||||
this.updateProgress();
|
||||
}
|
||||
|
||||
return gcode.getFinal();
|
||||
return gcode.getGCode();
|
||||
};
|
||||
D3D.Slicer.prototype.getGcode = function (printer) {
|
||||
D3D.Slicer.prototype.getGCode = function (printer) {
|
||||
"use strict";
|
||||
|
||||
var layerHeight = printer.config["printer.layerHeight"];
|
||||
@ -597,7 +609,7 @@ D3D.Slicer.prototype.getGcode = function (printer) {
|
||||
console.log("Data: " + (end - start) + "ms");
|
||||
|
||||
start = new Date().getTime();
|
||||
var gcode = this.dataToGcode(data, printer);
|
||||
var gcode = this.dataToGCode(data, printer);
|
||||
end = new Date().getTime();
|
||||
console.log("Gcode: " + (end - start) + "ms");
|
||||
|
||||
|
@ -7,6 +7,7 @@ D3D.SlicerWorker = function () {
|
||||
this.worker.addEventListener('message', function (event) {
|
||||
switch (event.data['cmd']) {
|
||||
case 'PROGRESS':
|
||||
|
||||
if (scope.onprogress !== undefined) {
|
||||
var progress = event.data['progress'];
|
||||
|
||||
|
57
src/utils.js
57
src/utils.js
@ -1,7 +1,7 @@
|
||||
/******************************************************
|
||||
*
|
||||
* Utils
|
||||
* requires jQuery, Three.js
|
||||
* dependices Three.js
|
||||
*
|
||||
******************************************************/
|
||||
|
||||
@ -14,6 +14,37 @@ var D3D = {
|
||||
function sendAPI (url, data, callback) {
|
||||
"use strict";
|
||||
|
||||
/*
|
||||
var form = new FormData();
|
||||
|
||||
for (var i in data) {
|
||||
form.append(i, JSON.stringify(data[i]));
|
||||
}
|
||||
|
||||
var request = new XMLHttpRequest();
|
||||
request.open('POST', url, true);
|
||||
request.send(data);
|
||||
request.onreadystatechange = function () {
|
||||
if (request.readyState === 4 && request.status === 200) {
|
||||
var response = JSON.parse(request.responseText);
|
||||
|
||||
if (response.status === "success") {
|
||||
if (callback !== undefined) {
|
||||
callback(response.data);
|
||||
}
|
||||
}
|
||||
else {
|
||||
console.warn(response.msg);
|
||||
}
|
||||
}
|
||||
else {
|
||||
console.log(request);
|
||||
console.warn("Failed connecting to " + url);
|
||||
//sendAPI(url, data, callback);
|
||||
}
|
||||
};
|
||||
*/
|
||||
|
||||
$.ajax({
|
||||
url: url,
|
||||
type: "POST",
|
||||
@ -38,6 +69,29 @@ function sendAPI (url, data, callback) {
|
||||
|
||||
function getAPI (url, callback) {
|
||||
"use strict";
|
||||
/*
|
||||
var request = new XMLHttpRequest();
|
||||
request.open('GET', url, true);
|
||||
request.send();
|
||||
request.onreadystatechange = function () {
|
||||
if (request.readyState === 4 && request.status === 200) {
|
||||
var response = JSON.parse(request.responseText);
|
||||
|
||||
if (response.status === "success") {
|
||||
if (callback !== undefined) {
|
||||
callback(response.data);
|
||||
}
|
||||
}
|
||||
else {
|
||||
console.warn(response.msg);
|
||||
}
|
||||
}
|
||||
else {
|
||||
console.warn("Failed connecting to " + url);
|
||||
sendAPI(url, callback);
|
||||
}
|
||||
};*/
|
||||
|
||||
|
||||
$.ajax({
|
||||
url: url,
|
||||
@ -57,6 +111,7 @@ function getAPI (url, callback) {
|
||||
console.warn("Failed connecting to " + url);
|
||||
getAPI(url, callback);
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
function loadSettings (url, callback) {
|
||||
|
@ -16,7 +16,6 @@ slicer.onProgress = function (progress) {
|
||||
"progress": progress
|
||||
});
|
||||
|
||||
//console.log(progress);
|
||||
};
|
||||
|
||||
self.addEventListener("message", function (event) {
|
||||
@ -42,7 +41,7 @@ self.addEventListener("message", function (event) {
|
||||
break;
|
||||
|
||||
case "SLICE":
|
||||
var gcode = slicer.getGcode(printer);
|
||||
var gcode = slicer.getGCode(printer);
|
||||
|
||||
self.postMessage({
|
||||
"cmd": "GCODE",
|
||||
|
@ -16,7 +16,7 @@ canvas {border: 1px solid black;}
|
||||
#progress {height: 20px; width: 200px; border: 1px solid black; overflow: hidden;}
|
||||
#progress_bar {height: 20px; background-color: lightblue; width: 0%;}
|
||||
.block {border: 1px solid black; width: 400px; height: 400px; display: inline-block;}
|
||||
#start_print {display: none;}
|
||||
#start_print, #download {display: none;}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
@ -33,8 +33,9 @@ canvas {border: 1px solid black;}
|
||||
<p>Total Lines: <span id='total_lines'></span></p>
|
||||
<p>Batches To Send: <span id='print_batches'></span></p>
|
||||
<div id='progress'><div id='progress_bar'></div></div>
|
||||
<button id="start_print">Start Print</button>
|
||||
<button id="stop_print">Stop Print</button>
|
||||
<button id="start_print">Start Print</button>
|
||||
<button id="download">Download Gcode</button>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
@ -48,10 +49,7 @@ function init () {
|
||||
var localIp = location.hash.substring(1);
|
||||
doodleBox = new D3D.Box(localIp);
|
||||
|
||||
printer = new D3D.Printer().updateConfig(USER_SETTINGS).updateConfig(PRINTER_SETTINGS['ultimaker2go']);
|
||||
|
||||
doodleBox.onupdate = function (data) {
|
||||
|
||||
document.getElementById('state').innerHTML = data.state;
|
||||
document.getElementById('bed_temp').innerHTML = data.bed;
|
||||
document.getElementById('bed_target_temp').innerHTML = data.bed_target;
|
||||
@ -63,6 +61,8 @@ function init () {
|
||||
document.getElementById('print_batches').innerHTML = doodleBox.printBatches.length;
|
||||
};
|
||||
|
||||
printer = new D3D.Printer().updateConfig(USER_SETTINGS).updateConfig(PRINTER_SETTINGS['ultimaker2go']);
|
||||
|
||||
document.getElementById('stop_print').onclick = function () {
|
||||
doodleBox.stopPrint(printer);
|
||||
};
|
||||
@ -77,22 +77,30 @@ function init () {
|
||||
};
|
||||
slicer.onfinish = function (_gcode) {
|
||||
gcode = _gcode;
|
||||
var button = document.getElementById('start_print');
|
||||
button.style.display = 'initial';
|
||||
button.onclick = function () {
|
||||
var startPrintButton = document.getElementById('start_print');
|
||||
var downloadButton = document.getElementById('download');
|
||||
|
||||
startPrintButton.style.display = 'initial';
|
||||
startPrintButton.onclick = function () {
|
||||
doodleBox.print(gcode);
|
||||
};
|
||||
|
||||
downloadButton.style.display = 'initial';
|
||||
downloadButton.onclick = function () {
|
||||
downloadFile("gcode.gcode", gcode.join('\n'));
|
||||
};
|
||||
};
|
||||
|
||||
var loader = new THREE.STLLoader();
|
||||
loader.load('models/pokemon/pikachu.stl', function (geometry) {
|
||||
var geometry = new THREE.TorusGeometry(20, 10, 30, 30).clone();
|
||||
loader.load('models/dom.stl', function (geometry) {
|
||||
//var geometry = new THREE.TorusGeometry(20, 10, 30, 30).clone();
|
||||
|
||||
var material = new THREE.MeshPhongMaterial({color: 0x00ff00, wireframe: false});
|
||||
//var material = new THREE.MeshBasicMaterial({color: 0x000000, wireframe: true});
|
||||
var mesh = new THREE.Mesh(geometry, material);
|
||||
|
||||
mesh.rotation.x = -Math.PI/2;
|
||||
mesh.scale.x = mesh.scale.y = mesh.scale.z = 0.5;
|
||||
mesh.scale.x = mesh.scale.y = mesh.scale.z = 1;
|
||||
mesh.position.y = -0.1;
|
||||
mesh.position.x = 60;
|
||||
mesh.position.z = 60;
|
||||
|
Loading…
Reference in New Issue
Block a user