Animating Three.js vertices - animation

I'm trying to animate individual vertices from a collada model.
The vertices ARE animating fine once but then they don't animate anymore.
1: Load my collada
// name obj
var orgVerts = false;
var desVerts = false;
var material = new THREE.MeshBasicMaterial({ color:0x1e5679, wireframe:true });
var loader = new THREE.ColladaLoader();
var nameModel = false;
loader.options.convertUpAxis = true;
loader.load( '3d/name.dae', function ( collada ) {
nameModel = collada.scene.children[0].children[0];
nameModel.material = material;
nameModel.geometry.dynamic = true;
nameModel.position.set(0,0,0);//x,z,y- if you think in blender dimensions ;)
nameModel.scale.x = .0035;
nameModel.scale.y = .0035;
nameModel.scale.z = .0035;
scene.add(nameModel);
orgVerts = nameModel.geometry.vertices; // make a backup of all verts
genVerts(); // create a new array of random verts
});
2: in my render function
var render = function () {
requestAnimationFrame(render);
// do stuff
if(nameModel){
if(window.globalCurrentSlide != 0){
for(var r=0; r < nameModel.geometry.vertices.length; r++){
var vert = desVerts[r]; // loop through all the destination verts
nameModel.geometry.vertices[r].x = nameModel.geometry.vertices[r].x - (nameModel.geometry.vertices[r].x - vert.x)/20;
nameModel.geometry.vertices[r].y = nameModel.geometry.vertices[r].y - (nameModel.geometry.vertices[r].y - vert.y)/20;
nameModel.geometry.vertices[r].z = nameModel.geometry.vertices[r].z - (nameModel.geometry.vertices[r].z - vert.z)/20;
}
}else{
for(var t=0; t < nameModel.geometry.vertices.length; t++){
var vert2 = orgVerts[t]; // loop through all the original verts
nameModel.geometry.vertices[t].x = nameModel.geometry.vertices[t].x - (nameModel.geometry.vertices[t].x - vert2.x)/20;
nameModel.geometry.vertices[t].y = nameModel.geometry.vertices[t].y - (nameModel.geometry.vertices[t].y - vert2.y)/20;
nameModel.geometry.vertices[t].z = nameModel.geometry.vertices[t].z - (nameModel.geometry.vertices[t].z - vert2.z)/20;
}
}
nameModel.geometry.verticesNeedUpdate = true;
nameModel.rotation.y += .005;
}
renderer.render( scene, camera );
}
window.globalCurrentSlide is set to 0 to start with and everything is fine. if I change window.globalCurrentSlide to 1, all the vertices animate correctly... BUT when I change window.globalCurrentSlide back to 0 the vertices don't animate back to their original positions. I've debugged heaps and can 100% say that BOTH desVerts and orgVerts don't change and they are correct. Any ideas? It's driving me nuts.
PS: I know the code could be condensed, I'm just playing ATM

The answer was that my orgVerts was just a reference NOT a clone. use:
var geometry = nameModel.geometry.clone();
orgVerts = geometry.vertices;

Related

raycaster Intersection isn't accurate after moving vertices

I'm having issue with raycaster.intersectObjects() after moving vertices of a geometry.. It doesn't intersect with the new geometry, it only intersects with the part that overlaps the original area. The object looks correctly modified in the view. I've been trying to search for an answer but none of the solutions seem to be working. I'm not sure what is wrong.
//move parts/vertices
for(var p=0; p<latticeModel.selected.length; p++){
var partNum = latticeModel.selected[p];
if(latticeModel.part[partNum].children[1].visible==true){
latticeModel.part[partNum].position.add(vector);
latticeCloud.tiles.part[partNum].position.add(vector);
}else{
var localVector = vector.clone();
localVector.add(latticeCloud.tiles.part[partNum].position);
latticeCloud.tiles.part[partNum].worldToLocal(localVector);
for(var v=0; v<4; v++){
if( latticeCloud.tiles.colors[partNum][v].getHex() == 0xfe0000 ||
latticeCloud.tiles.colors[partNum][v].getHex() == 0xff00ff ){
latticeCloud.tiles.part[partNum].geometry.vertices[v].add(localVector);
latticeCloud.tiles.part[partNum].geometry.verticesNeedUpdate = true;
latticeModel.part[partNum].children[0].geometry.vertices[v].add(localVector);
latticeModel.part[partNum].children[0].geometry.verticesNeedUpdate = true;
//added these below to try and debug, but still won't help
latticeModel.part[partNum].children[0].geometry.normalsNeedUpdate = true;
latticeModel.part[partNum].children[0].geometry.elementsNeedUpdate = true;
latticeModel.part[partNum].children[0].geometry.tangentsNeedUpdate = true;
latticeModel.part[partNum].children[0].geometry.computeFaceNormals = true;
latticeModel.part[partNum].children[0].geometry.computeVertexNormals = true;
latticeModel.part[partNum].children[0].geometry.computeBoundingBox = true;
latticeModel.part[partNum].children[0].geometry.computeBoundingSphere = true;
}
}
}
}
Here is the intersect part:
mouse.x = 2 * (e.clientX / window.innerWidth) - 1;
mouse.y = 1 - 2 * (e.clientY / window.innerHeight);
var vector = new THREE.Vector3(mouse.x, mouse.y, 0.5).unproject(camera);
var raycaster = new THREE.Raycaster(camera.position, vector.sub(camera.position).normalize());
scene.updateMatrixWorld();
//find the part mouse is overlapping and highlight it.
mouse.intersects = raycaster.intersectObjects(latticeModel.part, true);
if(mouse.intersects.length){
var foundPart = latticeModel.part.indexOf(mouse.intersects[0].object.parent);
if(foundPart!=mouse.selectedPart){
if(latticeModel.part.length>mouse.selectedPart && mouse.selectedPart!=-1){
latticeModel.part[mouse.selectedPart].children[2].visible = false;
}
mouse.selectedPart = foundPart;
latticeModel.part[mouse.selectedPart].children[2].visible = true;
}
}else{
if(latticeModel.part.length>mouse.selectedPart && mouse.selectedPart!=-1){
latticeModel.part[mouse.selectedPart].children[2].visible = false;
mouse.selectedPart = -1;
}
}
If you modify the vertices of a geometry, the geometry's bounding sphere and bounding box may become invalid.
The raycasting code will recompute them for you, but you need to set the following:
geometry.boundingSphere = null;
geometry.boundingBox = null;
three.js r.71

THREE.js (r60) PointLight not reflected by a special plane object (heightmapped from image)

UPDATE Cause of problem has been found - see Update section end of question.
I have a complex app using THREE.js (r60) which adds a special plane object to the main scene. The plane geometry is determined by heightmapping from an internally-supplied base64 uri image (size 16x16, 32x32 or 64x64 pixels). The scene has two static lights (ambient and directional) and one moveable point light which switches on and off.
In the complex app the point light is not reflected by the plane object. (Point light is toggled by pressing "R" key or button).
I have made a first JSFiddle example using THREE.js latest version (r70) where the lights work fine.
[Update] I have now made a second JSFiddle example using the older THREE.js library (r60) it also works OK.
I suspect the problem in the complex app (r60) may have something to do with system capacity and or timing/sequencing. Capacity is definitely an issue because other simpler scene objects (boxes and cylinders) show individual responses or non-responses to the point light which vary from one run of the app to the next, seemingly depending on the overall level of system activity (cpu, memory usage). These simpler objects may reflect in one run but not in the next. But the heightmapped plane object is consistently non-reflective to the point light. These behaviors are observed on (i) a Win7 laptop and (ii) an Android Kitkat tablet.
The heightmapping process may be part of the cause. I say this because when I comment out the heightmapped plane and activate a simple similar plane object (with randomly assigned z-levels) the latter plane behaves as expected (i.e. it reflects point light).
I guess that the usual approach now would be to upgrade my complex app to r70 (not a trivial step) and then start disabling chunks of the app to narrow down the cause. However it may be that the way in which heightmapping is implemented (e.g. with a callback) is a factor in explaining the failure of the heightmapped plane to reflect point light.
[RE-WRITTEN] So I would be grateful if anyone could take a look at the code in the correctly-working, previously-cited, (r70) JSFiddle example and point out any glaring design faults which (if applied in more complex, heavilly-loaded apps) might lead to failure of the height-mapped plane to reflect point light.
Full code (javascript, not html or css) of the (r70) JSFiddle:-
//... Heightmap from Image file
//... see http://danni-three.blogspot.co.uk/2013/09/threejs-heightmaps.html
var camera, scene, renderer;
var lpos_x = -60,lpos_y = 20,lpos_z = 100;
var mz = 1;
var time = 0, dt = 0;
var MyPlane, HPlane;
base64_imgData = "data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEAeAB4AAD/4QBoRXhpZgAATU0AKgAAAAgABAEaAAUAAAABAAAAPgEbAAUAAAABAAAARgEoAAMAAAABAAIAAAExAAIAAAASAAAATgAAAAAAAAB4AAAAAQAAAHgAAAABUGFpbnQuTkVUIHYzLjUuMTAA/9sAQwANCQoLCggNCwsLDw4NEBQhFRQSEhQoHR4YITAqMjEvKi4tNDtLQDQ4RzktLkJZQkdOUFRVVDM/XWNcUmJLU1RR/9sAQwEODw8UERQnFRUnUTYuNlFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFR/8AAEQgAIAAgAwEiAAIRAQMRAf/EAB8AAAEFAQEBAQEBAAAAAAAAAAABAgMEBQYHCAkKC//EALUQAAIBAwMCBAMFBQQEAAABfQECAwAEEQUSITFBBhNRYQcicRQygZGhCCNCscEVUtHwJDNicoIJChYXGBkaJSYnKCkqNDU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6g4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2drh4uPk5ebn6Onq8fLz9PX29/j5+v/EAB8BAAMBAQEBAQEBAQEAAAAAAAABAgMEBQYHCAkKC//EALURAAIBAgQEAwQHBQQEAAECdwABAgMRBAUhMQYSQVEHYXETIjKBCBRCkaGxwQkjM1LwFWJy0QoWJDThJfEXGBkaJicoKSo1Njc4OTpDREVGR0hJSlNUVVZXWFlaY2RlZmdoaWpzdHV2d3h5eoKDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uLj5OXm5+jp6vLz9PX29/j5+v/aAAwDAQACEQMRAD8A19Z8SXdu5KOMKxBAFOi1uTUdNJguxFcAchv6Vz2so/mzKc8sc8VX8MyQjUVWYNweCO9AEsOuX8s+xrqWQh8DJ4rsJCphSN3Czsm7ArG1bT7fSFe7EZJzuX3J6VQsdRnvryJ2+/wooA6O501JY7yRh0U8Vyg1WzsghhsAkqnBO4nd713t8NsEqIhJfqRXEahotxPJlISDnOaANzWvL1rR4JiTG6ryorG0C2aDUI02lhu6kVZ02wvLVSpYtu65yRXQaZYvDL5rhRx2oA//2Q==";
init();
animate();
//==================================================================
function init() {
scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 10);
camera.position.x = 1300;
camera.position.y = 400;
camera.position.z = 0;
camera.lookAt(0, 0, 0);
scene.add(camera);
scene.add(new THREE.AmbientLight(0x001900));
SunLight = new THREE.DirectionalLight(0xff0000,.3,20000);//...color, intensity, range.
SunLight.position.set(0, 3000, -8000);
scene.add(SunLight);
//POINT LIGHT
PL_color = 0x0000ff;
PL_intensity = 10;
PL_range_to_zero_intensity = 1200;
PL = new THREE.PointLight(PL_color, PL_intensity, PL_range_to_zero_intensity);
scene.add(PL);
PL_pos_x = -100;
PL_pos_y = -100;
PL_pos_z = 120;
PL.position.set(PL_pos_x, PL_pos_y, PL_pos_z);
//INDICATOR SPHERE
var s_Geometry = new THREE.SphereGeometry(5, 20, 20);
var s_Material = new THREE.MeshBasicMaterial({
color: 0xaaaaff
});
i_Sphere = new THREE.Mesh(s_Geometry, s_Material);
i_Sphere.position.set(PL_pos_x, PL_pos_y, PL_pos_z);
scene.add(i_Sphere);
//Plane02
var Plane02Geo = new THREE.PlaneGeometry(50, 50); //...
var Plane02Material = new THREE.MeshPhongMaterial({
side: THREE.DoubleSide
}, {
color: 0xaaaaaa
});
Plane02 = new THREE.Mesh(Plane02Geo, Plane02Material);
Plane02.position.set(0, 0, -120);
scene.add(Plane02);
//PEAS
xxx = SOW_F_Make_peas();
//RENDERER
renderer = new THREE.WebGLRenderer({
antialias: true
});
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.shadowMapEnabled = true;
renderer.shadowMapSoft = false;
document.body.appendChild(renderer.domElement);
// controls
controls = new THREE.OrbitControls(camera, renderer.domElement);
xxx = SOW_F_Make_Heightmap_Object_from_Image_File(scene, camera);
} //...EOFunction Init
//==================================================================
function animate() {
dt = 0.1;
time += dt;
if (time < 10000) {
requestAnimationFrame(animate);
//move point light & indicator sphere
speed = 16;
if (Math.abs(PL_pos_z) > 400) mz = (-1)* mz;
PL_pos_x += 0.01 * speed * mz;
PL_pos_y += 0.05 * speed * mz;
PL_pos_z -= 0.2 * speed * mz;
PL.position.set(PL_pos_x, PL_pos_y, PL_pos_z);
i_Sphere.position.set(PL_pos_x, PL_pos_y, PL_pos_z);
renderer.render(scene, camera);
} else alert("Time=" + time + "Finished");
}
//==================================================================
function SOW_F_Make_Heightmap_Object_from_Image_File(givenScene, givenCamera) {
//... Read a Heightmap from a coloured image file
//... into a (pre-defined global) plane object called HPlane
MyImage = new Image();
MyImage.onload = function () {
var MyPlane_width = 1000;//6000; //...MyPlane width or height are in scene units and do not have to match image width or height
var MyPlane_height = 1000;//6000;
var MyPlane_w_segs = MyImage.naturalWidth - 1; //... important that this mapping is correct for texture 1 pixel :: 1 segment.
var MyPlane_h_segs = MyImage.naturalHeight - 1; //... important that this mapping is correct for texture 1 pixel :: 1 segment.
var Hgeometry = new THREE.PlaneGeometry(MyPlane_width, MyPlane_height, MyPlane_w_segs, MyPlane_h_segs);
//var texture = THREE.ImageUtils.loadTexture( '/images/Tri_VP_Texturemap.jpg' );
var texture = THREE.ImageUtils.loadTexture( base64_imgData );
//... Choose texture or color
//var Hmaterial = new THREE.MeshLambertMaterial( { map: texture, side: THREE.DoubleSide} );//....fails
var Hmaterial = new THREE.MeshPhongMaterial( {
color: 0x111111 , side: THREE.DoubleSide } ); //... works OK
HPlane = new THREE.Mesh(Hgeometry, Hmaterial);
//...get Height Data from Image
var scale = 0.6;//1//6; //0.25;
var Height_data = DA_getHeightData(MyImage, scale);
//... set height of vertices
X_offset = 0;
Y_offset = 0;
Z_offset = -100; //...this will (after rotation) add to the vertical height dimension (+ => up).
for (var iii = 0; iii < HPlane.geometry.vertices.length; iii++) {
//HPlane.geometry.vertices[iii].x = X_offset;
//HPlane.geometry.vertices[iii].y = Y_offset;
HPlane.geometry.vertices[iii].z = Z_offset + Height_data[iii];
}
//----------------------------------------------------------------------
//... Must do it in this order...Faces before Vertices
//... see WestLangley's response in http://stackoverflow.com/questions/13943907/my-object-isnt-reflects-the-light-in-three-js
HPlane.rotation.x = (-(Math.PI) / 2); //... rotate MyPlane -90 degrees on X
//alert("Rotated");
HPlane.geometry.computeFaceNormals(); //... for Lambert & Phong materials
HPlane.geometry.computeVertexNormals(); //... for Lambert & Phong materials
/*
HPlane.updateMatrixWorld();
HPlane.matrixAutoUpdate = false;
HPlane.geometry.verticesNeedUpdate = true;
*/
givenScene.add(HPlane);
HPlane.position.set(0, -150, 0);//... cosmetic
//return HPlane; //... not necessary, given that HPlane is global.
} ; //... End of MyImage.onload = function ()
//===============================================================
//... *** IMPORTANT ***
//... Only NOW do we command the script to actually load the image source
//... This .src statement will load the image from file into MyImage object
//... and invoke the pre-associated MyImage.OnLoad function
//... cause cross-origin problem: MyImage.src = '/images/Tri_VP_Heightmap_64x64.jpg'; //...if image file is local to this html file.
MyImage.src = base64_imgData;//... uses image data provided in the script to avoid Cross-origin file source restrictions.
} //... End of function SOW_F_Make_Heightmap_Object_from_Image_File
//===========================================================================
function DA_getHeightData(d_img, scale) {
//... This is used by function SOW_F_Make_Heightmap_Object_from_Image_File.
//if (scale == undefined) scale=1;
var canvas = document.createElement('canvas');
canvas.width = d_img.width; //OK
canvas.height = d_img.height;
var context = canvas.getContext('2d');
var size = d_img.width * d_img.height;
var data = new Float32Array(size);
context.drawImage(d_img, 0, 0);
for (var ii = 0; ii < size; ii++) {
data[ii] = 0;
}
var imgData = context.getImageData(0, 0, d_img.width, d_img.height);
var pix = imgData.data; //... Uint(8) UnClamped Array[1024] for a 16x16 = 256 pixel image = 4 slots per pixel.
var jjj = 0;
//... presumably each pix cell can have value 0 to 255
for (var iii = 0; iii < pix.length; iii += 4) {
var all = pix[iii] + pix[iii + 1] + pix[iii + 2];
//... I guess RGBA and we don't use the fourth cell (A, = Alpha channel)
jjj++;
data[jjj] = all * scale / 3; //...original code used 12 not 3 ??? and divided by scale.
//console.log (iii, all/(3*scale), data[jjj]);
}
return data;
} //... end of function DA_getHeightData(d_img,scale)
//==================================================================================================
function SOW_F_Get_A_Plane(givenScene, givenCamera) {
//...MyPlane width or height are in scene units and do not have to match image width or height
var MyPlane_width = 1000;
var MyPlane_height = 1000;
var MyPlane_w_segs = 64; //...
var MyPlane_h_segs = 64; //...
geometry = new THREE.PlaneGeometry(MyPlane_width, MyPlane_height, MyPlane_w_segs, MyPlane_h_segs);
//var material = new THREE.MeshLambertMaterial( { color: 0xeeee00, side: THREE.DoubleSide} );
var material = new THREE.MeshPhongMaterial({
color: 0xeeee00,side: THREE.DoubleSide
}); //... OK
MyPlane = new THREE.Mesh(geometry, material);
givenScene.add(MyPlane);
MyPlane.rotation.x = (-(Math.PI) / 2); // rotate it -90 degrees on X
MyPlane.position.set(0, 100, 0);
MyPlane.geometry.computeFaceNormals(); //...for Lambert & Phong materials
MyPlane.geometry.computeVertexNormals(); //...for Lambert & Phong materials
/*
MyPlane.geometry.verticesNeedUpdate = true;
MyPlane.updateMatrixWorld();
MyPlane.matrixAutoUpdate = false;
*/
} //... EOF SOW_F_Get_A_Plane
//====================================================================
function SOW_F_Make_peas()
{
//----------------- Make an array of spheres -----------------------
Pea_geometry = new THREE.SphereGeometry(5,16,16);
//Pea_material = new THREE.MeshNormalMaterial({ shading: THREE.SmoothShading});
Pea_material = new THREE.MeshPhongMaterial({ color: 0xaa5522});
// global...
num_peas = 1200;
for (var iii = 0; iii < num_peas; iii++)
{
//...now global
ob_Pea = new THREE.Mesh(Pea_geometry, Pea_material);
ob_Pea.position.set(
400 * Math.random() - 150,
300 * Math.random() - 150,
1200 * Math.random() - 150);
scene.add(ob_Pea);//TEST
}
}
UPDATE
It appears the problem is a result of phasing. See this new JSFiddle(r70). Pointlight is created in function init() but not added to scene, or is immediately removed from scene after being added. Then various graphical mesh objects are created. When pointlight is added back to the scene (in the animate loop) it is too late - the mesh objects will not be illuminated by the pointlight.
A procedural solution is simply to not remove pointlights from the scene if they are to be used later. If they need to be "extinguished" temporarilly then just turn down the intensity and turn it up later: e.g.
myPointLight.intensity = 0.00

Attach text above 3D Object

I'm wondering if it is possible to attach a text above a 3D Object?
If so, how would I do it?
So far I'm doing the following below to load a mesh with its material and lastly adding it to a THREE.Object3D(); and adding it to the scene. Works great without any problems.
Next step is I want to show a nice text above its this object that is always fixed and can be seen from every angle.
loader.load('assets/' + enemyUrl, function (geometry, materials) {
material = new THREE.MeshFaceMaterial( materials );
model = new THREE.SkinnedMesh( geometry, material );
var mats = model.material.materials;
for (var i = 0,length = mats.length; i < length; i++) {
var m = mats[i];
m.skinning = true;
}
ensureLoop(geometry.animations[0]);
function ensureLoop( tmp ) {
for ( var i = 0; i < tmp.hierarchy.length; i ++ ) {
var bone = tmp.hierarchy[ i ];
var first = bone.keys[ 0 ];
var last = bone.keys[ bone.keys.length - 1 ];
last.pos = first.pos;
last.rot = first.rot;
last.scl = first.scl;
}
}
model.scale.set(2.5,2.5,2.5);
// TODO: Randomize where to put it in the world
yawObject.position.y = spawnPosition.y;
yawObject.position.x = spawnPosition.x;
yawObject.position.z = spawnPosition.z;
yawObject.add(model);
scene.add(yawObject);
});
Something like this:
This is what my game looks like now:
sure its possible. you can create a canvas with text on it, which you use as a texture on a plane that always looks at the camera, you could also do it with a single particle, but im not quite sure how it would work since particle materials have a size parameter. something like:
var name = 'Rovdjuret';
var canvas = document.createElement('canvas');
var ctx = canvas.getContext("2d");
ctx.font="20px Georgia";
ctx.fillText(name,10,50);
var texture = new THREE.Texture(canvas);
texture.needsUpdate = true; //just to make sure it's all up to date.
var label = new THREE.Mesh(new THREE.PlaneGeometry, new THREE.MeshBasicMaterial({map:texture}));
and inside the render/animation loop you make all the labels look at the camera:
label.lookAt(camera.position);

Accessing single particles in THREE.js Particle System

I really tried every example, searched the web for hours but I can't seem to get it working!
So I simply tried to implement a little particle system simulating falling snow, just like this: http://www.aerotwist.com/tutorials/creating-particles-with-three-js/
But I only can access it in whole. Meaning I can rotate it as such but as soon as I try to iterate over it's vertices, the whole animation is getting the hiccups! I would really appreciate some help here!
-
Here are the key parts:
-> Setting up the particle system:
var partikelGeo = new THREE.Geometry();
var partikelMaterial = new THREE.ParticleBasicMaterial({
color:0xffffff,
size: 10,
map: THREE.ImageUtils.loadTexture('snowflake2.png'),
blending: THREE.AdditiveBlending,
transparent:true
});
var partikelAnzahl = 3500;
for (var p = 0; p < partikelAnzahl; p++) {
var pX = Math.random() * 1000 -500;
var pY = Math.random() * 1000 -500;
var pZ = Math.random() * 1000 -500;
var partikel = new THREE.Vertex(new THREE.Vector3(pX,pY,pZ));
partikel.velocity = new THREE.Vector3(0,-Math.random(),0);
partikelGeo.vertices.push(partikel);
}
var partikelSystem = new THREE.ParticleSystem(partikelGeo, partikelMaterial);
partikelSystem.sortParticles = true;
scene.add(partikelSystem);
-> Rendering & Animation on mouseclick
var frame = 0;
function animate(){
// request new frame
requestAnimationFrame(function(){
animate();
});
// render
render();
}
animate();
var check = 0;
onmousedown = function(){
if (check) {
check = 0;
}else{
check = 1;
}
}
function render() {
if (check) {
clickDo();
}
camera.lookAt(new THREE.Vector3(0,0,0));
renderer.render(scene,camera);
}
function clickDo() {
frame++;
partikelSystem.rotation.y += 0.01;
var pCount = partikelAnzahl;
while(pCount--) {
// get the particle
var particle =
partikelGeo.vertices[pCount];
// check if we need to reset
if(particle.position.y < -200) {
particle.position.y = 200;
particle.velocity.y = 0;
}
// update the velocity with
// a splat of randomniz
particle.velocity.y -=
Math.random() * .1;
// and the position
particle.position.addSelf(
particle.velocity);
}
// flag to the particle system
// that we've changed its vertices.
partikelSystem.
geometry.
__dirtyVertices = true;
}
Rah
Your code looks good to me. I would just suggest to try not sorting your particles as you use an additive blending:
partikelSystem.sortParticles = false;

Three.js - Updating texture on plane

I'm trying to make a terrain editor. So I have a plane with multiple materials on it, which I initialize like so:
var materials = [];
var grasstexture = THREE.ImageUtils.loadTexture('Img/grass.png', {}, function() { });
var rocktexture = THREE.ImageUtils.loadTexture('Img/rock.png', {}, function() { });
materials.push(new THREE.MeshPhongMaterial({color: 0xffffff, map: grasstexture}));
materials.push(new THREE.MeshPhongMaterial({color: 0xffffff, map: rocktexture}));
// Plane
this.geometry.materials = materials;
for(var i = 0; i < this.geometry.faces.length; i++)
{
this.geometry.faces[i].materialIndex = 0;
}
this.geometry.dynamic = true;
this.mesh = new THREE.Mesh( this.geometry, new THREE.MeshFaceMaterial( ) );
this.mesh.receiveShadow = true;
The result is a square plane stripped with the two textures.
Now, I can't seem to update the materialIndex for each vertex during the runtime. I have tried:
face.materialIndex = 1;
for(var i = 0; i < geo.materials.length; i++){
geo.materials[i].needsUpdate = true;
}
for(var i = 0; i < this.geometry.faces.length; i++)
{
geo.faces[i].materialIndex = 0;
}
for(var i = 0; i < geo.materials.length; i++){
geo.materials[i].needsUpdate = true;
}
this.mesh.needsUpdate = true;
this.mesh.material.needsUpdate = true;
geo.verticesNeedUpdate = true;
geo.normalsNeedUpdate = true;
geo.colorsNeedUpdate = true;
geo.computeFaceNormals();
geo.computeVertexNormals();
geo.computeCentroids();
geo.computeTangents() ;
And every other 'materialIndex' and 'needsUpdate' variable in Three.js I was able to find, but still nothing happens. How do I force an update on the material indices?
You can't. materialIndex is only used in the first render to partition the geometry into chunks, with each chunk having the same material. Also, you cannot re-partition the chunks.
What you can do, however, is change a material in the materials array.
materials[ 0 ] = new THREE.MeshBasicMaterial();
You do not need to set any needsUpdate flags to true after doing so, either.
An alternate thing you can do is give each face it's own material from the start, and then, for example, just change a material's texture.
mesh.geometry.materials[ 0 ].map = texture;
texture.needsUpdate = true;

Resources