我有一个在你点击另一个时创建网格的功能。在点击上,创建2或3个网格并转到它们的位置。知道我想做反向功能:当部署网格时,你点击网格上的anoter时间,先前创建的网格会返回并从场景中移除。
这是我的第一个功能:
function sortiSphere(element, obj) {
var matStdParams = {
roughness: 1,
metalness: 0.8,
color: element.group,
emissive: element.group,
emissiveIntensity: 0.5
};
var sphereMaterial2 = new THREE.MeshStandardMaterial(matStdParams);
var mesh = new THREE.Mesh(sphereGeometry, sphereMaterial2);
mesh.position.x = x;
mesh.position.y = y;
mesh.position.z = z;
mesh.userData.children = element.children;
mesh.userData.name = element.label;
mesh.userData.rang = element.rang;
mesh.userData.def = element.définition;
mesh.userData.posx = element.posx;
mesh.userData.posy = element.posy;
mesh.userData.posz = element.posz;
mesh.userData.parent = obj;
mesh.userData.cartabs = element.cartabs;
mesh.position.normalize();
mesh.position.multiplyScalar(1 / element.rang);
mesh.scale.set(1 / (element.rang / 2), 1 / (element.rang / 2), 1 / (element.rang / 2))
mesh.position.x = obj.position.x;
mesh.position.y = obj.position.y;
mesh.position.z = obj.position.z;
var x = element.posx;
var y = element.posy;
var z = element.posz;
new TWEEN.Tween(mesh.position).to({
x: x,
y: y,
z: z
}, 1000)
.easing(TWEEN.Easing.Elastic.Out).start();
console.log(mesh);
scene.add(mesh);
lesMesh.push(mesh)
// lines
var material = new THREE.LineBasicMaterial({
color: 0xffffff
});
var geometry = new THREE.Geometry();
geometry.vertices.push(
obj.position,
new THREE.Vector3(x, y, z)
);
var line = new THREE.Line(geometry, material);
scene.add(line);
gen1 = [];
gen2 = [];
gen3 = [];
gen4 = [];
gen5 = [];
obj.userData.bool = true;
};
请注意,网格包含有关其状态的信息:userData.bool(如果已部署,则为true,否则为false)
现在,我该如何告诉他们回去?
以下是我现在所得到的:
function deleteSphere(element, obj) {
console.log("--- deleteSphere / debut fonction")
for (i = 0; gen1.length > i; i++) {
if (gen1[i].userData.children) {
for (j = 0; gen1[i].userData.children.length > j; j++) {
console.log(gen2[i][j]);
scene.remove(gen2[i][j]);}
} else {
scene.remove(gen1[i])
console.log(gen1[i].userData.children)
}
}
};
感谢您的时间
答案 0 :(得分:0)
当您使用tween.js时,您可以使用其.onUpdate()
和.onComplete()
方法。
这不是最终的解决方案,这只是一个从头开始的例子。
让我们的基础对象有一个容器:
var bases = new THREE.Group();
scene.add(bases);
现在我们需要一个事件,我们将创建我们的基础对象,让它点击一个按钮:
btnAdd.addEventListener("click", setBase);
我们的setBase()
函数将如下所示:
var rndBase = function() {
return THREE.Math.randFloatSpread(10);
}
function setBase() {
var base = new THREE.Mesh(new THREE.SphereGeometry(.5, 8, 4), new THREE.MeshBasicMaterial({
color: Math.random() * 0xffffff
}));
base.position.set(rndBase(), rndBase(), rndBase());
bases.add(base);
}
一切准备就绪,我们可以从点击基础对象开始。让它成为mousedown
的事件监听器:
window.addEventListener("mousedown", setOrRemove, false);
var raycaster = new THREE.Raycaster();
var mouse = new THREE.Vector2();
var intersects;
var obj;
function setOrRemove(event) {
mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;
raycaster.setFromCamera(mouse, camera);
intersects = raycaster.intersectObjects(bases.children);
if (intersects.length > 0) {
obj = intersects[0].object;
if (obj.children.length != 0) { // simple check for existence of children
removeObj(obj); // if children were deployed, then remove them and their parent (base object)
} else {
setChildren(obj); // otherwise, as a base object has no children, then we'll add some
}
}
}
最有趣的部分从这里开始。
让我们设置孩子们:
function setChildren(parent) {
let radius = Math.random() + 1;
for (let i = 0; i < THREE.Math.randInt(2, 3); i++) { //as you said there are 2 or 3 children
var child = new THREE.Mesh(new THREE.BoxGeometry(.25, .25, .25), new THREE.MeshBasicMaterial({
color: parent.material.color,
wireframe: true
}));
child.userData.direction = new THREE.Vector3(rndBase(), rndBase(), rndBase()).normalize(); // random direction (must be a normalized vector)
child.userData.radius = radius;
parent.add(child);
}
let start = { val: 0 };
let end = { val: 1 };
new TWEEN.Tween(start).to(end, 1000) // we simply change from 0 to 1 during 1 second
.easing(TWEEN.Easing.Elastic.Out)
.onUpdate( // here we'll update position of each children in accordance to direction and radius
function() {
parent.children.forEach((child) => {
child.position.copy(child.userData.direction).multiplyScalar(child.userData.radius * this.val);
})
}
)
.start();
}
删除基础对象及其子对象是:
function removeObj(baseObj) { // very similar to how we created children
let start = { val: 1 };
let end = { val: 0 };
new TWEEN.Tween(start).to(end, 1000)
.easing(TWEEN.Easing.Elastic.In)
.onUpdate(
function(){
baseObj.children.forEach((child) => {
child.position.copy(child.userData.direction).multiplyScalar(child.userData.radius * this.val);
})
}
)
.onComplete( // but the difference is here, it allow us to perform something when our tweening is completed
function() {
for (let i = baseObj.children - 1; i = 0; i--) {
baseObj.remove(baseObj.children[i]); //and here we simply delete children in reverse order
}
bases.remove(baseObj); //and then we remove the base object itself
}
)
.start()
}
所以,就是这样。别忘了把TWEEN.update();
放在我们的动画循环中:)
jsfiddle示例r86。