mirror of
https://github.com/tengge1/ShadowEditor.git
synced 2026-01-25 15:08:11 +00:00
样条编辑器。
This commit is contained in:
parent
1d072cec82
commit
b97ec30f0b
253
ShadowEditor.Web/src/editor/spline/SplineEditor.js
Normal file
253
ShadowEditor.Web/src/editor/spline/SplineEditor.js
Normal file
@ -0,0 +1,253 @@
|
||||
var container, stats;
|
||||
var camera, scene, renderer;
|
||||
var splineHelperObjects = [];
|
||||
var splinePointsLength = 4;
|
||||
var positions = [];
|
||||
var point = new THREE.Vector3();
|
||||
var geometry = new THREE.BoxBufferGeometry(20, 20, 20);
|
||||
var transformControl;
|
||||
var ARC_SEGMENTS = 200;
|
||||
var splines = {};
|
||||
|
||||
var params = {
|
||||
uniform: true,
|
||||
tension: 0.5,
|
||||
centripetal: true,
|
||||
chordal: true,
|
||||
addPoint: addPoint,
|
||||
removePoint: removePoint,
|
||||
exportSpline: exportSpline
|
||||
};
|
||||
|
||||
function SplineEditor(container) {
|
||||
container = document.getElementById('container');
|
||||
scene = new THREE.Scene();
|
||||
scene.background = new THREE.Color(0xf0f0f0);
|
||||
camera = new THREE.PerspectiveCamera(70, window.innerWidth / window.innerHeight, 1, 10000);
|
||||
camera.position.set(0, 250, 1000);
|
||||
scene.add(camera);
|
||||
scene.add(new THREE.AmbientLight(0xf0f0f0));
|
||||
var light = new THREE.SpotLight(0xffffff, 1.5);
|
||||
light.position.set(0, 1500, 200);
|
||||
light.castShadow = true;
|
||||
light.shadow = new THREE.LightShadow(new THREE.PerspectiveCamera(70, 1, 200, 2000));
|
||||
light.shadow.bias = - 0.000222;
|
||||
light.shadow.mapSize.width = 1024;
|
||||
light.shadow.mapSize.height = 1024;
|
||||
scene.add(light);
|
||||
var planeGeometry = new THREE.PlaneBufferGeometry(2000, 2000);
|
||||
planeGeometry.rotateX(- Math.PI / 2);
|
||||
var planeMaterial = new THREE.ShadowMaterial({ opacity: 0.2 });
|
||||
var plane = new THREE.Mesh(planeGeometry, planeMaterial);
|
||||
plane.position.y = - 200;
|
||||
plane.receiveShadow = true;
|
||||
scene.add(plane);
|
||||
var helper = new THREE.GridHelper(2000, 100);
|
||||
helper.position.y = - 199;
|
||||
helper.material.opacity = 0.25;
|
||||
helper.material.transparent = true;
|
||||
scene.add(helper);
|
||||
//var axes = new THREE.AxesHelper( 1000 );
|
||||
//axes.position.set( - 500, - 500, - 500 );
|
||||
//scene.add( axes );
|
||||
renderer = new THREE.WebGLRenderer({ antialias: true });
|
||||
renderer.setPixelRatio(window.devicePixelRatio);
|
||||
renderer.setSize(window.innerWidth, window.innerHeight);
|
||||
renderer.shadowMap.enabled = true;
|
||||
container.appendChild(renderer.domElement);
|
||||
stats = new Stats();
|
||||
container.appendChild(stats.dom);
|
||||
var gui = new dat.GUI();
|
||||
gui.add(params, 'uniform');
|
||||
gui.add(params, 'tension', 0, 1).step(0.01).onChange(function (value) {
|
||||
splines.uniform.tension = value;
|
||||
updateSplineOutline();
|
||||
});
|
||||
gui.add(params, 'centripetal');
|
||||
gui.add(params, 'chordal');
|
||||
gui.add(params, 'addPoint');
|
||||
gui.add(params, 'removePoint');
|
||||
gui.add(params, 'exportSpline');
|
||||
gui.open();
|
||||
// Controls
|
||||
var controls = new THREE.OrbitControls(camera, renderer.domElement);
|
||||
controls.damping = 0.2;
|
||||
controls.addEventListener('change', render);
|
||||
controls.addEventListener('start', function () {
|
||||
cancelHideTransorm();
|
||||
});
|
||||
controls.addEventListener('end', function () {
|
||||
delayHideTransform();
|
||||
});
|
||||
transformControl = new THREE.TransformControls(camera, renderer.domElement);
|
||||
transformControl.addEventListener('change', render);
|
||||
transformControl.addEventListener('dragging-changed', function (event) {
|
||||
controls.enabled = !event.value;
|
||||
});
|
||||
scene.add(transformControl);
|
||||
// Hiding transform situation is a little in a mess :()
|
||||
transformControl.addEventListener('change', function () {
|
||||
cancelHideTransorm();
|
||||
});
|
||||
transformControl.addEventListener('mouseDown', function () {
|
||||
cancelHideTransorm();
|
||||
});
|
||||
transformControl.addEventListener('mouseUp', function () {
|
||||
delayHideTransform();
|
||||
});
|
||||
transformControl.addEventListener('objectChange', function () {
|
||||
updateSplineOutline();
|
||||
});
|
||||
var dragcontrols = new THREE.DragControls(splineHelperObjects, camera, renderer.domElement); //
|
||||
dragcontrols.enabled = false;
|
||||
dragcontrols.addEventListener('hoveron', function (event) {
|
||||
transformControl.attach(event.object);
|
||||
cancelHideTransorm();
|
||||
});
|
||||
dragcontrols.addEventListener('hoveroff', function () {
|
||||
delayHideTransform();
|
||||
});
|
||||
var hiding;
|
||||
function delayHideTransform() {
|
||||
cancelHideTransorm();
|
||||
hideTransform();
|
||||
}
|
||||
function hideTransform() {
|
||||
hiding = setTimeout(function () {
|
||||
transformControl.detach(transformControl.object);
|
||||
}, 2500);
|
||||
}
|
||||
function cancelHideTransorm() {
|
||||
if (hiding) clearTimeout(hiding);
|
||||
}
|
||||
/*******
|
||||
* Curves
|
||||
*********/
|
||||
for (var i = 0; i < splinePointsLength; i++) {
|
||||
addSplineObject(positions[i]);
|
||||
}
|
||||
positions = [];
|
||||
for (var i = 0; i < splinePointsLength; i++) {
|
||||
positions.push(splineHelperObjects[i].position);
|
||||
}
|
||||
var geometry = new THREE.BufferGeometry();
|
||||
geometry.addAttribute('position', new THREE.BufferAttribute(new Float32Array(ARC_SEGMENTS * 3), 3));
|
||||
var curve = new THREE.CatmullRomCurve3(positions);
|
||||
curve.curveType = 'catmullrom';
|
||||
curve.mesh = new THREE.Line(geometry.clone(), new THREE.LineBasicMaterial({
|
||||
color: 0xff0000,
|
||||
opacity: 0.35
|
||||
}));
|
||||
curve.mesh.castShadow = true;
|
||||
splines.uniform = curve;
|
||||
curve = new THREE.CatmullRomCurve3(positions);
|
||||
curve.curveType = 'centripetal';
|
||||
curve.mesh = new THREE.Line(geometry.clone(), new THREE.LineBasicMaterial({
|
||||
color: 0x00ff00,
|
||||
opacity: 0.35
|
||||
}));
|
||||
curve.mesh.castShadow = true;
|
||||
splines.centripetal = curve;
|
||||
curve = new THREE.CatmullRomCurve3(positions);
|
||||
curve.curveType = 'chordal';
|
||||
curve.mesh = new THREE.Line(geometry.clone(), new THREE.LineBasicMaterial({
|
||||
color: 0x0000ff,
|
||||
opacity: 0.35
|
||||
}));
|
||||
curve.mesh.castShadow = true;
|
||||
splines.chordal = curve;
|
||||
for (var k in splines) {
|
||||
var spline = splines[k];
|
||||
scene.add(spline.mesh);
|
||||
}
|
||||
load([new THREE.Vector3(289.76843686945404, 452.51481137238443, 56.10018915737797),
|
||||
new THREE.Vector3(- 53.56300074753207, 171.49711742836848, - 14.495472686253045),
|
||||
new THREE.Vector3(- 91.40118730204415, 176.4306956436485, - 6.958271935582161),
|
||||
new THREE.Vector3(- 383.785318791128, 491.1365363371675, 47.869296953772746)]);
|
||||
}
|
||||
|
||||
SplineEditor.prototype.addSplineObject = function (position) {
|
||||
var material = new THREE.MeshLambertMaterial({ color: Math.random() * 0xffffff });
|
||||
var object = new THREE.Mesh(geometry, material);
|
||||
if (position) {
|
||||
object.position.copy(position);
|
||||
} else {
|
||||
object.position.x = Math.random() * 1000 - 500;
|
||||
object.position.y = Math.random() * 600;
|
||||
object.position.z = Math.random() * 800 - 400;
|
||||
}
|
||||
object.castShadow = true;
|
||||
object.receiveShadow = true;
|
||||
scene.add(object);
|
||||
splineHelperObjects.push(object);
|
||||
return object;
|
||||
};
|
||||
|
||||
SplineEditor.prototype.addPoint = function () {
|
||||
splinePointsLength++;
|
||||
positions.push(addSplineObject().position);
|
||||
updateSplineOutline();
|
||||
};
|
||||
|
||||
SplineEditor.prototype.removePoint = function () {
|
||||
if (splinePointsLength <= 4) {
|
||||
return;
|
||||
}
|
||||
splinePointsLength--;
|
||||
positions.pop();
|
||||
scene.remove(splineHelperObjects.pop());
|
||||
updateSplineOutline();
|
||||
};
|
||||
|
||||
SplineEditor.prototype.updateSplineOutline = function () {
|
||||
for (var k in splines) {
|
||||
var spline = splines[k];
|
||||
var splineMesh = spline.mesh;
|
||||
var position = splineMesh.geometry.attributes.position;
|
||||
for (var i = 0; i < ARC_SEGMENTS; i++) {
|
||||
var t = i / (ARC_SEGMENTS - 1);
|
||||
spline.getPoint(t, point);
|
||||
position.setXYZ(i, point.x, point.y, point.z);
|
||||
}
|
||||
position.needsUpdate = true;
|
||||
}
|
||||
};
|
||||
|
||||
SplineEditor.prototype.exportSpline = function () {
|
||||
var strplace = [];
|
||||
for (var i = 0; i < splinePointsLength; i++) {
|
||||
var p = splineHelperObjects[i].position;
|
||||
strplace.push('new THREE.Vector3({0}, {1}, {2})'.format(p.x, p.y, p.z));
|
||||
}
|
||||
console.log(strplace.join(',\n'));
|
||||
var code = '[' + (strplace.join(',\n\t')) + ']';
|
||||
prompt('copy and paste code', code);
|
||||
}
|
||||
|
||||
SplineEditor.prototype.load = function (new_positions) {
|
||||
while (new_positions.length > positions.length) {
|
||||
addPoint();
|
||||
}
|
||||
while (new_positions.length < positions.length) {
|
||||
removePoint();
|
||||
}
|
||||
for (var i = 0; i < positions.length; i++) {
|
||||
positions[i].copy(new_positions[i]);
|
||||
}
|
||||
updateSplineOutline();
|
||||
};
|
||||
|
||||
SplineEditor.prototype.animate = function () {
|
||||
requestAnimationFrame(animate);
|
||||
render();
|
||||
stats.update();
|
||||
};
|
||||
|
||||
SplineEditor.prototype.render = function () {
|
||||
splines.uniform.mesh.visible = params.uniform;
|
||||
splines.centripetal.mesh.visible = params.centripetal;
|
||||
splines.chordal.mesh.visible = params.chordal;
|
||||
renderer.render(scene, camera);
|
||||
};
|
||||
|
||||
export default SplineEditor;
|
||||
@ -3,4 +3,12 @@ window.BlobBuilder = window.BlobBuilder || window.WebKitBlobBuilder || window.Mo
|
||||
|
||||
Number.prototype.format = function () {
|
||||
return this.toString().replace(/(\d)(?=(\d{3})+(?!\d))/g, "$1,");
|
||||
};
|
||||
|
||||
String.prototype.format = function () {
|
||||
var str = this;
|
||||
for (var i = 0; i < arguments.length; i++) {
|
||||
str = str.replace('{' + i + '}', arguments[i]);
|
||||
}
|
||||
return str;
|
||||
};
|
||||
Loading…
x
Reference in New Issue
Block a user