Morphing Geometry - Three.Js - javascript

So I have this code that will generate the user's desired dimension and display it on a customized new THREE.Geometry() . This may be an off topic to most of you. But hey, I'm just new to Three.js
My problem is that:
I can't find a way to insert the geometry.morphTargets. Or simply, I don't know how to use it properly
So here's my code:
//custom Object height and width
customHeightWidth(customWidth, customHeight);
function customHeightWidth(width, height){
material = new THREE.MeshBasicMaterial({
map: THREE.ImageUtils.loadTexture(uploadedFile),
side: THREE.DoubleSide,
overdraw: true,
wireframe: false
});
//objects
combined = new THREE.PlaneGeometry(width, height, 30, 10);
geometry = new THREE.Geometry();
geometry.name: "target1", vertices.push( new THREE.Vector3( -(width), height, 0 ) );
geometry.name: "target2", vertices.push( new THREE.Vector3( -(width), -(height), 0 ) );
geometry.name: "target3", vertices.push( new THREE.Vector3( width, -(height), 0 ) );
geometry.computeBoundingSphere();
geometry.faces.push( new THREE.Face3( 0, 1, 2 ) );
geometry1 = new THREE.Geometry();
geometry1.vertices.push( new THREE.Vector3( width, height, 0 ) );
geometry1.vertices.push( new THREE.Vector3( -(width), height, 0 ) );
geometry1.vertices.push( new THREE.Vector3( width, -(height), 0 ) );
geometry1.computeBoundingSphere();
geometry1.faces.push( new THREE.Face3( 0, 1, 2 ) );
// 1st box
var mesh1 = new THREE.Mesh(geometry);
var mesh2 = new THREE.Mesh(geometry1);
//activating the meshs
THREE.GeometryUtils.merge(combined, mesh1);
THREE.GeometryUtils.merge(combined, mesh2);
mesh = new THREE.Mesh(combined, material);
this.scene.add(mesh);
};
}
var animate = function() {
requestAnimationFrame(animate);
//mesh.rotation.x += 0.01;
//mesh.rotation.y -= 0.006;
renderer.render(scene, camera);
}
init();
animate();

I recommend reviewing how JSONLoader loads morph targets to the Geometry.morphTargets array in the Geometry class.
function parseMorphing( scale ) {
if ( json.morphTargets !== undefined ) {
var i, l, v, vl, dstVertices, srcVertices;
for ( i = 0, l = json.morphTargets.length; i < l; i ++ ) {
geometry.morphTargets[ i ] = {};
geometry.morphTargets[ i ].name = json.morphTargets[ i ].name;
geometry.morphTargets[ i ].vertices = [];
dstVertices = geometry.morphTargets[ i ].vertices;
srcVertices = json.morphTargets [ i ].vertices;
for( v = 0, vl = srcVertices.length; v < vl; v += 3 ) {
var vertex = new THREE.Vector3();
vertex.x = srcVertices[ v ] * scale;
vertex.y = srcVertices[ v + 1 ] * scale;
vertex.z = srcVertices[ v + 2 ] * scale;
dstVertices.push( vertex );
}
}
}

//Reading morphTargets
for(i=o;i<geometry.morphTargets.length;i++) {
morphTargets = geometry.morphTargets[i].vertices;
return morphTargets;
}
//loading morphTargets
loadMorphTargets = function (morphTargets) {
if (morphTargets !== undefined) {
var i, l, v, vl, dstVertices, srcVertices;
//for (i = 0, l = morphTargets.length; i < l; i++) {
geometry.morphTargets[i] = {};
geometry.morphTargets[i].name = morphTargets.name;
geometry.morphTargets[i].vertices = [];
var dstVertices = geometry.morphTargets[i].vertices;
var srcVertices = morphTargets.vertices;
for (v = 0, vl = srcVertices.length; v < vl; v += 3) {
var vertex = new THREE.Vector3();
vertex.x = srcVertices[ v ];
vertex.y = srcVertices[ v + 1 ];
vertex.z = srcVertices[ v + 2 ];
dstVertices.push(vertex);
}
}
};
I guess it will be useful to you.

Related

(THREE.JS) calculate the custom UVs for custom Buffer Geometry

I am trying to create a curve wall using some vertices array in three JS.
What I will get in array is some base vertices in 2D which will be the bottom vertices of wall. These includes the center, lower and upper vertices which means it is two faced wall. based on these vertices, I added some wall height and convert that 2D to 3D.
Below is the code and working fiddle
/**
* Created by Singh on 7/30/2018.
*/
var renderer, scene, camera;
init();
animate();
function init() {
wallsGeometry = function(totalPoints){
var material = new THREE.MeshBasicMaterial({/*color: 0xff0000,*/ side: THREE.DoubleSide, wireframe : false});
var material2 = new THREE.MeshBasicMaterial({/*color: 0x0044400, */side: THREE.DoubleSide, wireframe : true});
var geometry = new THREE.BufferGeometry();
var geometry2 = new THREE.BufferGeometry();
var wallHeight = 200;
var pointindices = [
0,1,2,0,2,3, //left
5,4,7,5,7,6, //right
4,0,3,4,3,7, //back
1,5,6,1,6,2, //front
2,6,7,2,7,3, //top
5,1,0,5,0,4, //bottom
];
var pointindices2 = [
1,0,2,1,3,2 , //left
4,5,7,4,6,7, //right
0,4,3,0,7,3, //back
5,1,2,5,2,6, //front
6,2,7,6,3,7, //top
1,5,0,1,4,0, //bottom
];
var tempIndices = [];
var tempIndices2 = [];
for(var i=0; i<4; i++) {
for (var j = 0; j < pointindices.length; j++) {
tempIndices[pointindices.length * i + j] = 4 * i + pointindices[j];
}
}
for(var i=0; i<4; i++) {
for (var j = 0; j < pointindices2.length; j++) {
tempIndices2[pointindices2.length * i + j] = 4 * i + pointindices2[j];
}
}
var tempVerMesh = [];
var tempVerMesh2 = [];
var indices = new Uint32Array( tempIndices );
var pointsArray = { // for testing
pointUpper1: new THREE.Vector3(),
pointUpper2: new THREE.Vector3(),
pointCenter1: new THREE.Vector3(),
pointCenter2: new THREE.Vector3(),
pointLower1: new THREE.Vector3(),
pointLower2: new THREE.Vector3()
};
console.log(totalPoints);
/*function generateUVs(geometry) {
geometry.computeBoundingBox();
var max = geometry.boundingBox.max, min = geometry.boundingBox.min;
var offset = new THREE.Vector3(0 - min.x, 0 - min.y);
var range = new THREE.Vector3(max.x - min.x, max.y - min.y);
var faces = geometry.faces;
geometry.faceVertexUvs[0] = [];
for (var i = 0; i < faces.length ; i++) {
var v1 = geometry.vertices[faces[i].a],
v2 = geometry.vertices[faces[i].b],
v3 = geometry.vertices[faces[i].c];
geometry.faceVertexUvs[0].push([
new THREE.Vector3((v1.x + offset.x)/range.x ,(v1.y + offset.y)/range.y),
new THREE.Vector3((v2.x + offset.x)/range.x ,(v2.y + offset.y)/range.y),
new THREE.Vector3((v3.x + offset.x)/range.x ,(v3.y + offset.y)/range.y),
]);
}
geometry.uvsNeedUpdate = true;
return geometry;
}*/
for (var i = 0; i < totalPoints.lower.length ; i++) {
pointsArray.pointCenter1 = totalPoints.center[i];
//pointsArray.pointCenter2 = totalPoints.center[i + 1];
pointsArray.pointLower1 = totalPoints.lower[i];
//pointsArray.pointLower2 = totalPoints.lower[i + 1];
pointsArray.pointUpper1 = totalPoints.upper[i];
//pointsArray.pointUpper2 = totalPoints.upper[i + 1];
tempVerMesh.push(pointsArray.pointCenter1.x, pointsArray.pointCenter1.y, pointsArray.pointCenter1.z);
tempVerMesh.push(pointsArray.pointLower1.x, pointsArray.pointLower1.y, pointsArray.pointLower1.z);
tempVerMesh.push(pointsArray.pointLower1.x, pointsArray.pointLower1.y + wallHeight, pointsArray.pointLower1.z);
tempVerMesh.push(pointsArray.pointCenter1.x, pointsArray.pointCenter1.y + wallHeight, pointsArray.pointCenter1.z);
tempVerMesh2.push(pointsArray.pointCenter1.x, pointsArray.pointCenter1.y, pointsArray.pointCenter1.z);
tempVerMesh2.push(pointsArray.pointUpper1.x, pointsArray.pointUpper1.y, pointsArray.pointUpper1.z);
tempVerMesh2.push(pointsArray.pointUpper1.x, pointsArray.pointUpper1.y + wallHeight, pointsArray.pointUpper1.z );
tempVerMesh2.push(pointsArray.pointCenter1.x, pointsArray.pointCenter1.y + wallHeight, pointsArray.pointCenter1.z);
}
var vertices = new Float32Array(tempVerMesh);
var vertices2 = new Float32Array(tempVerMesh2);
//var uvs = new Float32Array(pointUVs);
geometry.addAttribute('position', new THREE.BufferAttribute(vertices, 3));
geometry.setIndex(new THREE.BufferAttribute(indices, 1));
//geometry.addAttribute('uv', new THREE.BufferAttribute(uvs, 2));
geometry.computeFaceNormals();
geometry.computeVertexNormals();
console.log(geometry);
var mesh = new THREE.Mesh(geometry, material);
var indices2 = new Uint32Array(tempIndices2);
geometry2.addAttribute('position', new THREE.BufferAttribute(vertices2, 3));
geometry2.setIndex(new THREE.BufferAttribute(indices2, 1));
geometry2.computeFaceNormals();
geometry2.computeVertexNormals();
/*var geom = new THREE.Geometry().fromBufferGeometry(geometry2);
var temp = generateUVs(geom);
geometry2 = new THREE.BufferGeometry().fromGeometry(temp);*/
var mesh2 = new THREE.Mesh(geometry2, material2);
//geometry2.addAttribute('uv', new THREE.BufferAttribute(uvs2, 2));
return [mesh,mesh2];
};
camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 1, 10000);
camera.position.z = 400;
scene = new THREE.Scene();
var arrow;
var rayCaster = new THREE.Raycaster();
var mouse = new THREE.Vector2();
renderer = new THREE.WebGLRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );
renderer.domElement.addEventListener("mousemove", onMouseMove);
var points = {
pointUpper1: new THREE.Vector3(-70, 0, -20),
pointUpper2: new THREE.Vector3(130, 0, -20),
pointCenter1: new THREE.Vector3(-100, 0, 0),
pointCenter2: new THREE.Vector3(150, 0, 0),
pointLower1: new THREE.Vector3(-70, 0, 20),
pointLower2: new THREE.Vector3(130, 0, 20)
};
var totalPoints = {
center : [new THREE.Vector3(-70, 0, 0),new THREE.Vector3(0, 0, 0),new THREE.Vector3(50, 0, 0),new THREE.Vector3(100, 0, 0),new THREE.Vector3(130, 0, 0)],
lower : [new THREE.Vector3(-70, 0, 20),new THREE.Vector3(0, 0, 20),new THREE.Vector3(50, 0, 20),new THREE.Vector3(100, 0, 20),new THREE.Vector3(130, 0, 20)],
upper : [new THREE.Vector3(-70, 0, -20),new THREE.Vector3(0, 0, -20),new THREE.Vector3(50, 0, -20),new THREE.Vector3(100, 0, -20),new THREE.Vector3(130, 0, -20)]
};
var sphere = new THREE.SphereGeometry(2, 10, 10);
function initPoints(){
var point1mesh = new THREE.Mesh(sphere, new THREE.MeshBasicMaterial({color: 0xff00}));
point1mesh.position.copy(points.pointUpper1);
scene.add(point1mesh);
var point2mesh = new THREE.Mesh(sphere, new THREE.MeshBasicMaterial({color: 0x0000ff}));
point2mesh.position.copy(points.pointUpper2);
scene.add(point2mesh);
var point3mesh = new THREE.Mesh(sphere, new THREE.MeshBasicMaterial({color: 0xff00}));
point3mesh.position.copy(points.pointCenter1);
scene.add(point3mesh);
var point4mesh = new THREE.Mesh(sphere, new THREE.MeshBasicMaterial({color: 0x0000ff}));
point4mesh.position.copy(points.pointCenter2);
scene.add(point4mesh);
var point5mesh = new THREE.Mesh(sphere, new THREE.MeshBasicMaterial({color: 0xff00}));
point5mesh.position.copy(points.pointLower1);
scene.add(point5mesh);
var point6mesh = new THREE.Mesh(sphere, new THREE.MeshBasicMaterial({color: 0x0000ff}));
point6mesh.position.copy(points.pointLower2);
scene.add(point6mesh);
}
initPoints();
var mesh = new wallsGeometry(totalPoints);
function createArrow() {
var length = 30;
arrow = new THREE.ArrowHelper(
THREE.Object3D.DefaultUp,
new THREE.Vector3(),
length,
0xffff00,
1.5 * length,
1.25 * length
);
arrow.position.z = 10;
scene.add(arrow);
}
// arrow
createArrow();
function updateArrow(object, point, face) {
arrow.position.copy(point);
var normalMatrix = new THREE.Matrix3().getNormalMatrix( object.matrixWorld );
var normal = face.normal.clone().applyMatrix3( normalMatrix ).normalize();
arrow.setDirection(normal);
}
function onMouseMove(event) {
mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;
rayCaster.setFromCamera(mouse, camera);
var intersects = rayCaster.intersectObject(mesh[0], true);
var i, il, intersect;
if (intersects[0]) {
var face = intersects[0].face;
var point = intersects[0].point;
var object = intersects[0].object;
updateArrow(object, point, face);
}
}
/* var textureLoader = new THREE.TextureLoader();
textureLoader.load('./textures/Capture.PNG', function (texture) {
console.log('texture loaded');
texture.minFilter = THREE.LinearFilter;
//mesh[0].material.map = texture;
var vertexNormalsHelper = new THREE.VertexNormalsHelper( mesh[0], 10 );
mesh[0].add( vertexNormalsHelper );
}); */
scene.add(mesh[0]);
/* textureLoader.load('./textures/abc.jpg', function (texture) {
console.log('texture loaded');
texture.minFilter = THREE.LinearFilter;
//mesh[1].material.map = texture;
var vertexNormalsHelper = new THREE.VertexNormalsHelper( mesh[1], 10 );
mesh[1].add( vertexNormalsHelper );
}); */
scene.add(mesh[1]);
//
var Orbitcontrols = new THREE.OrbitControls(camera,renderer.domElement);
Orbitcontrols.update();
}
// render
function render() {
renderer.render(scene, camera);
}
// animate
function animate() {
requestAnimationFrame(animate);
render();
}
https://jsfiddle.net/simar_aneja/fsmw8znq/6/
In the fiddle you can see that wall is building properly and you can increase the vertices and loop of creating those indices, in the start. Now I want to add UVs to this bufferGeometry, I tried converting to geometry and then calculated faceVertexUVs, but this is not the right way. Can anyone suggest me the further path where I can attach different textures only at the front side, different on top side. And it should be in such a way that no matter how many vertices comes, Uvs should get calculated based on length of vertices. I have some Idea but not getting how to make it different for diff sides of wall.
Thanks
Here's a UV box-unwrapping I fixed up for ya. Maybe you'll find it helpful...
I also put your fiddle into a snippet you can run below...
function boxUnwrapUVs(geometry) {
if (!geometry.boundingBox) geometry.computeBoundingBox();
var sz = geometry.boundingBox.getSize(new THREE.Vector3());
var center = geometry.boundingBox.getCenter(new THREE.Vector3())
var min = geometry.boundingBox.min;
if (geometry.faceVertexUvs[0].length == 0) {
for (var i = 0; i < geometry.faces.length; i++) {
geometry.faceVertexUvs[0].push([new THREE.Vector2(), new THREE.Vector2(), new THREE.Vector2()]);
}
}
for (var i = 0; i < geometry.faces.length; i++) {
var face = geometry.faces[i];
var faceUVs = geometry.faceVertexUvs[0][i]
var va = geometry.vertices[geometry.faces[i].a]
var vb = geometry.vertices[geometry.faces[i].b]
var vc = geometry.vertices[geometry.faces[i].c]
var vab = new THREE.Vector3().copy(vb).sub(va)
var vac = new THREE.Vector3().copy(vc).sub(va)
//now we have 2 vectors to get the cross product of...
var vcross = new THREE.Vector3().copy(vab).cross(vac);
//Find the largest axis of the plane normal...
vcross.set(Math.abs(vcross.x), Math.abs(vcross.y), Math.abs(vcross.z))
var majorAxis = vcross.x > vcross.y ? (vcross.x > vcross.z ? 'x' : vcross.y > vcross.z ? 'y' : vcross.y > vcross.z) : vcross.y > vcross.z ? 'y' : 'z'
//Take the other two axis from the largest axis
var uAxis = majorAxis == 'x' ? 'y' : majorAxis == 'y' ? 'x' : 'x';
var vAxis = majorAxis == 'x' ? 'z' : majorAxis == 'y' ? 'z' : 'y';
faceUVs[0].set((va[uAxis] - min[uAxis]) / sz[uAxis], (va[vAxis] - min[vAxis]) / sz[vAxis])
faceUVs[1].set((vb[uAxis] - min[uAxis]) / sz[uAxis], (vb[vAxis] - min[vAxis]) / sz[vAxis])
faceUVs[2].set((vc[uAxis] - min[uAxis]) / sz[uAxis], (vc[vAxis] - min[vAxis]) / sz[vAxis])
}
geometry.elementsNeedUpdate = geometry.verticesNeedUpdate = true;
}
geometry = new THREE.Geometry().fromBufferGeometry(geometry)
boxUnwrapUVs(geometry)
var mesh = new THREE.Mesh(geometry, material);
/**
* Created by Singh on 7/30/2018.
*/
var renderer, scene, camera;
init();
animate();
function init() {
wallsGeometry = function(totalPoints) {
var rrnd = (min, max) => (Math.random() * (max - min)) + min
var irnd = (rng) => (Math.random() * rng) | 0
function makeRndCanvas() {
var canvas = document.createElement('canvas');
canvas.width = canvas.height = 128;
var ctx = canvas.getContext('2d');
var srnd = (rng) => (Math.random() - 0.5) * 2 * rng
var irnd = (rng) => ((Math.random() * rng) | 0)
for (var x = 0; x < canvas.width; x++) {
for (var y = 0; y < canvas.width; y++) {
ctx.fillStyle = `rgba(${irnd(256)},${irnd(256)},${irnd(256)},1.0)`
ctx.fillRect(x, y, 1, 1);
}
}
ctx.fillStyle = '#ffff00'
ctx.fillText("WAHOO", 3, 64)
return canvas;
}
function makeRndTexture() {
var tex = new THREE.Texture(makeRndCanvas())
tex.minFilter = // THREE.LinearMipMapLinearFilter;
tex.magFilter = THREE.NearestFilter; //THREE.LinearFilter;
tex.wrapS = tex.wrapT = THREE.RepeatWrapping;
//tex.repeat.set(0.01, 0.01);
tex.needsUpdate = true;
return tex;
}
var material = new THREE.MeshLambertMaterial({ /*color: 0xff0000,*/
side: THREE.DoubleSide,
wireframe: false,
map: makeRndTexture()
});
var material2 = new THREE.MeshLambertMaterial({ /*color: 0x0044400, */
side: THREE.DoubleSide,
wireframe: true
});
var geometry = new THREE.BufferGeometry();
var geometry2 = new THREE.BufferGeometry();
var wallHeight = 200;
var pointindices = [
0, 1, 2, 0, 2, 3, //left
5, 4, 7, 5, 7, 6, //right
4, 0, 3, 4, 3, 7, //back
1, 5, 6, 1, 6, 2, //front
2, 6, 7, 2, 7, 3, //top
5, 1, 0, 5, 0, 4, //bottom
];
var pointindices2 = [
1, 0, 2, 1, 3, 2, //left
4, 5, 7, 4, 6, 7, //right
0, 4, 3, 0, 7, 3, //back
5, 1, 2, 5, 2, 6, //front
6, 2, 7, 6, 3, 7, //top
1, 5, 0, 1, 4, 0, //bottom
];
var tempIndices = [];
var tempIndices2 = [];
for (var i = 0; i < 4; i++) {
for (var j = 0; j < pointindices.length; j++) {
tempIndices[pointindices.length * i + j] = 4 * i + pointindices[j];
}
}
for (var i = 0; i < 4; i++) {
for (var j = 0; j < pointindices2.length; j++) {
tempIndices2[pointindices2.length * i + j] = 4 * i + pointindices2[j];
}
}
var tempVerMesh = [];
var tempVerMesh2 = [];
var indices = new Uint32Array(tempIndices);
var pointsArray = { // for testing
pointUpper1: new THREE.Vector3(),
pointUpper2: new THREE.Vector3(),
pointCenter1: new THREE.Vector3(),
pointCenter2: new THREE.Vector3(),
pointLower1: new THREE.Vector3(),
pointLower2: new THREE.Vector3()
};
console.log(totalPoints);
/*function generateUVs(geometry) {
geometry.computeBoundingBox();
var max = geometry.boundingBox.max, min = geometry.boundingBox.min;
var offset = new THREE.Vector3(0 - min.x, 0 - min.y);
var range = new THREE.Vector3(max.x - min.x, max.y - min.y);
var faces = geometry.faces;
geometry.faceVertexUvs[0] = [];
for (var i = 0; i < faces.length ; i++) {
var v1 = geometry.vertices[faces[i].a],
v2 = geometry.vertices[faces[i].b],
v3 = geometry.vertices[faces[i].c];
geometry.faceVertexUvs[0].push([
new THREE.Vector3((v1.x + offset.x)/range.x ,(v1.y + offset.y)/range.y),
new THREE.Vector3((v2.x + offset.x)/range.x ,(v2.y + offset.y)/range.y),
new THREE.Vector3((v3.x + offset.x)/range.x ,(v3.y + offset.y)/range.y),
]);
}
geometry.uvsNeedUpdate = true;
return geometry;
}*/
for (var i = 0; i < totalPoints.lower.length; i++) {
pointsArray.pointCenter1 = totalPoints.center[i];
//pointsArray.pointCenter2 = totalPoints.center[i + 1];
pointsArray.pointLower1 = totalPoints.lower[i];
//pointsArray.pointLower2 = totalPoints.lower[i + 1];
pointsArray.pointUpper1 = totalPoints.upper[i];
//pointsArray.pointUpper2 = totalPoints.upper[i + 1];
tempVerMesh.push(pointsArray.pointCenter1.x, pointsArray.pointCenter1.y, pointsArray.pointCenter1.z);
tempVerMesh.push(pointsArray.pointLower1.x, pointsArray.pointLower1.y, pointsArray.pointLower1.z);
tempVerMesh.push(pointsArray.pointLower1.x, pointsArray.pointLower1.y + wallHeight, pointsArray.pointLower1.z);
tempVerMesh.push(pointsArray.pointCenter1.x, pointsArray.pointCenter1.y + wallHeight, pointsArray.pointCenter1.z);
tempVerMesh2.push(pointsArray.pointCenter1.x, pointsArray.pointCenter1.y, pointsArray.pointCenter1.z);
tempVerMesh2.push(pointsArray.pointUpper1.x, pointsArray.pointUpper1.y, pointsArray.pointUpper1.z);
tempVerMesh2.push(pointsArray.pointUpper1.x, pointsArray.pointUpper1.y + wallHeight, pointsArray.pointUpper1.z);
tempVerMesh2.push(pointsArray.pointCenter1.x, pointsArray.pointCenter1.y + wallHeight, pointsArray.pointCenter1.z);
}
var vertices = new Float32Array(tempVerMesh);
var vertices2 = new Float32Array(tempVerMesh2);
//var uvs = new Float32Array(pointUVs);
geometry.addAttribute('position', new THREE.BufferAttribute(vertices, 3));
geometry.setIndex(new THREE.BufferAttribute(indices, 1));
//geometry.addAttribute('uv', new THREE.BufferAttribute(uvs, 2));
geometry.computeFaceNormals();
geometry.computeVertexNormals();
console.log(geometry);
function boxUnwrapUVs(geometry) {
if (!geometry.boundingBox) geometry.computeBoundingBox();
var sz = geometry.boundingBox.getSize(new THREE.Vector3());
var center = geometry.boundingBox.getCenter(new THREE.Vector3())
var min = geometry.boundingBox.min;
if (geometry.faceVertexUvs[0].length == 0) {
for (var i = 0; i < geometry.faces.length; i++) {
geometry.faceVertexUvs[0].push([new THREE.Vector2(), new THREE.Vector2(), new THREE.Vector2()]);
}
}
for (var i = 0; i < geometry.faces.length; i++) {
var face = geometry.faces[i];
var faceUVs = geometry.faceVertexUvs[0][i]
var va = geometry.vertices[geometry.faces[i].a]
var vb = geometry.vertices[geometry.faces[i].b]
var vc = geometry.vertices[geometry.faces[i].c]
var vab = new THREE.Vector3().copy(vb).sub(va)
var vac = new THREE.Vector3().copy(vc).sub(va)
//now we have 2 vectors to get the cross product of...
var vcross = new THREE.Vector3().copy(vab).cross(vac);
//Find the largest axis of the plane normal...
vcross.set(Math.abs(vcross.x), Math.abs(vcross.y), Math.abs(vcross.z))
var majorAxis = vcross.x > vcross.y ? (vcross.x > vcross.z ? 'x' : vcross.y > vcross.z ? 'y' : vcross.y > vcross.z) : vcross.y > vcross.z ? 'y' : 'z'
//Take the other two axis from the largest axis
var uAxis = majorAxis == 'x' ? 'y' : majorAxis == 'y' ? 'x' : 'x';
var vAxis = majorAxis == 'x' ? 'z' : majorAxis == 'y' ? 'z' : 'y';
faceUVs[0].set((va[uAxis] - min[uAxis]) / sz[uAxis], (va[vAxis] - min[vAxis]) / sz[vAxis])
faceUVs[1].set((vb[uAxis] - min[uAxis]) / sz[uAxis], (vb[vAxis] - min[vAxis]) / sz[vAxis])
faceUVs[2].set((vc[uAxis] - min[uAxis]) / sz[uAxis], (vc[vAxis] - min[vAxis]) / sz[vAxis])
}
geometry.elementsNeedUpdate = geometry.verticesNeedUpdate = true;
}
geometry = new THREE.Geometry().fromBufferGeometry(geometry)
boxUnwrapUVs(geometry)
geometry = new THREE.BufferGeometry().fromGeometry(geometry)
var mesh = new THREE.Mesh(geometry, material);
var indices2 = new Uint32Array(tempIndices2);
geometry2.addAttribute('position', new THREE.BufferAttribute(vertices2, 3));
geometry2.setIndex(new THREE.BufferAttribute(indices2, 1));
geometry2.computeFaceNormals();
geometry2.computeVertexNormals();
/* var geom = new THREE.Geometry().fromBufferGeometry(geometry2);
var temp = generateUVs(geom);
geometry2 = new THREE.BufferGeometry().fromGeometry(temp);*/
var mesh2 = new THREE.Mesh(geometry2, material2);
//geometry2.addAttribute('uv', new THREE.BufferAttribute(uvs2, 2));
return [mesh, mesh2];
};
camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 1, 10000);
camera.position.z = 400;
scene = new THREE.Scene();
var arrow;
var rayCaster = new THREE.Raycaster();
var mouse = new THREE.Vector2();
renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
var light = new THREE.DirectionalLight();
light.position.set(200, 200, 200)
scene.add(light)
document.body.appendChild(renderer.domElement);
renderer.domElement.addEventListener("mousemove", onMouseMove);
var points = {
pointUpper1: new THREE.Vector3(-70, 0, -20),
pointUpper2: new THREE.Vector3(130, 0, -20),
pointCenter1: new THREE.Vector3(-100, 0, 0),
pointCenter2: new THREE.Vector3(150, 0, 0),
pointLower1: new THREE.Vector3(-70, 0, 20),
pointLower2: new THREE.Vector3(130, 0, 20)
};
var totalPoints = {
center: [new THREE.Vector3(-70, 0, 0), new THREE.Vector3(0, 0, 0), new THREE.Vector3(50, 0, 0), new THREE.Vector3(100, 0, 0), new THREE.Vector3(130, 0, 0)],
lower: [new THREE.Vector3(-70, 0, 20), new THREE.Vector3(0, 0, 20), new THREE.Vector3(50, 0, 20), new THREE.Vector3(100, 0, 20), new THREE.Vector3(130, 0, 20)],
upper: [new THREE.Vector3(-70, 0, -20), new THREE.Vector3(0, 0, -20), new THREE.Vector3(50, 0, -20), new THREE.Vector3(100, 0, -20), new THREE.Vector3(130, 0, -20)]
};
var sphere = new THREE.SphereGeometry(2, 10, 10);
function initPoints() {
var point1mesh = new THREE.Mesh(sphere, new THREE.MeshBasicMaterial({
color: 0xff00
}));
point1mesh.position.copy(points.pointUpper1);
scene.add(point1mesh);
var point2mesh = new THREE.Mesh(sphere, new THREE.MeshBasicMaterial({
color: 0x0000ff
}));
point2mesh.position.copy(points.pointUpper2);
scene.add(point2mesh);
var point3mesh = new THREE.Mesh(sphere, new THREE.MeshBasicMaterial({
color: 0xff00
}));
point3mesh.position.copy(points.pointCenter1);
scene.add(point3mesh);
var point4mesh = new THREE.Mesh(sphere, new THREE.MeshBasicMaterial({
color: 0x0000ff
}));
point4mesh.position.copy(points.pointCenter2);
scene.add(point4mesh);
var point5mesh = new THREE.Mesh(sphere, new THREE.MeshBasicMaterial({
color: 0xff00
}));
point5mesh.position.copy(points.pointLower1);
scene.add(point5mesh);
var point6mesh = new THREE.Mesh(sphere, new THREE.MeshBasicMaterial({
color: 0x0000ff
}));
point6mesh.position.copy(points.pointLower2);
scene.add(point6mesh);
}
initPoints();
var mesh = new wallsGeometry(totalPoints);
function createArrow() {
var length = 30;
arrow = new THREE.ArrowHelper(
THREE.Object3D.DefaultUp,
new THREE.Vector3(),
length,
0xffff00,
1.5 * length,
1.25 * length
);
arrow.position.z = 10;
scene.add(arrow);
}
// arrow
createArrow();
function updateArrow(object, point, face) {
arrow.position.copy(point);
var normalMatrix = new THREE.Matrix3().getNormalMatrix(object.matrixWorld);
var normal = face.normal.clone().applyMatrix3(normalMatrix).normalize();
arrow.setDirection(normal);
}
function onMouseMove(event) {
mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;
rayCaster.setFromCamera(mouse, camera);
var intersects = rayCaster.intersectObject(mesh[0], true);
var i, il, intersect;
if (intersects[0]) {
var face = intersects[0].face;
var point = intersects[0].point;
var object = intersects[0].object;
updateArrow(object, point, face);
}
}
/* var textureLoader = new THREE.TextureLoader();
textureLoader.load('./textures/Capture.PNG', function (texture) {
console.log('texture loaded');
texture.minFilter = THREE.LinearFilter;
//mesh[0].material.map = texture;
var vertexNormalsHelper = new THREE.VertexNormalsHelper( mesh[0], 10 );
mesh[0].add( vertexNormalsHelper );
}); */
scene.add(mesh[0]);
/* textureLoader.load('./textures/abc.jpg', function (texture) {
console.log('texture loaded');
texture.minFilter = THREE.LinearFilter;
//mesh[1].material.map = texture;
var vertexNormalsHelper = new THREE.VertexNormalsHelper( mesh[1], 10 );
mesh[1].add( vertexNormalsHelper );
}); */
scene.add(mesh[1]);
//
var Orbitcontrols = new THREE.OrbitControls(camera, renderer.domElement);
Orbitcontrols.update();
}
// render
function render() {
renderer.render(scene, camera);
}
// animate
function animate() {
requestAnimationFrame(animate);
render();
}
<script src="https://threejs.org/build/three.min.js"></script>
<script src="https://cdn.rawgit.com/mrdoob/three.js/master/examples/js/controls/OrbitControls.js"></script>

cloth simulator using three.js

I am working on three.js to create cloth simulator like hermes' website just difference is I wanted top-down waves instead of horozontal waves that is in hermes.
However I succeed to make vertical waves as I wanted (here is live also added snippet below)
but as you can see top side is not fixed it is also moving slightly I want to make top side Fixed it should not move like hermes website, and want to make this wave continuous instead of just once when webpage loads, also I noticed once wired thing that when I keep open my modified version in browser for 5-10 minutes it shrinks in size (height & width) and gets too smaller after sometime. I don't know why!!
Can any one expert here do some help me for this three things?
make top side fixed like hermes.
Continuous waves.
Get rid of size reducing.
function Particle( x, y, z, mass, drag, clothFunction ) {
this.position = clothFunction( x, y ); // position
this.previous = clothFunction( x, y ); // previous
this.original = clothFunction( x, y );
this.a = new THREE.Vector3( 0, 0, 0 ); // acceleration
this.mass = mass;
this.drag = drag;
this.invMass = 1 / mass;
this.tmp = new THREE.Vector3();
this.tmp2 = new THREE.Vector3();
}
Particle.prototype.addForce = function( force ) {
this.a.add(
this.tmp2.copy( force ).multiplyScalar( this.invMass )
);
};
Particle.prototype.integrate = function( timesq ) {
var newPos = this.tmp.subVectors( this.position, this.previous );
// newPos.multiplyScalar( this.drag ).add( this.position );
newPos.add( this.position );
newPos.add( this.a.multiplyScalar( timesq ) );
this.tmp = this.previous;
this.previous = this.position;
this.position = newPos;
this.a.set( 0, 0, 0 );
};
function Cloth( mass, w, h, restDistance, drag, clothFunction ) {
function index( u, v ) {
return u + v * ( w + 1 );
}
w = w || 10;
h = h || 10;
this.w = w;
this.h = h;
var particles = [];
var constraints = [];
var u, v;
// Create particles
for ( v = 0; v <= h; v ++ ) {
for ( u = 0; u <= w; u ++ ) {
particles.push(
new Particle( u / w, -v / h, 0, mass, drag, clothFunction )
);
}
}
// Structural
for ( v = 0; v < h; v ++ ) {
for ( u = 0; u < w; u ++ ) {
constraints.push( [
particles[ index( u, v ) ],
particles[ index( u, v + 1 ) ],
restDistance
] );
constraints.push( [
particles[ index( u, v ) ],
particles[ index( u + 1, v ) ],
restDistance
] );
}
}
for ( u = w, v = 0; v < h; v ++ ) {
constraints.push( [
particles[ index( u, v ) ],
particles[ index( u, v + 1 ) ],
restDistance
] );
}
for ( v = h, u = 0; u < w; u ++ ) {
constraints.push( [
particles[ index( u, v ) ],
particles[ index( u + 1, v ) ],
restDistance
] );
}
this.particles = particles;
this.constraints = constraints;
this.index = index;
}
function animatedProduct( container, size, canvas, image ) {
this.DAMPING = .02;
this.DRAG = 1 - this.DAMPING
this.MASS = 2000;
this.STIFFNESS = 1;
this.SEGMENTS = 40;
this.canvas = canvas;
this.size = size;
this.demoMode = !0;
this.startTime = Date.now();
this.image = image;
this.restDistance = this.size / this.SEGMENTS;
this.container = container;
this.gravity = new THREE.Vector3( 0, -80, 0 ).multiplyScalar( this.MASS );
this.TIMESTEP_SQ = Math.pow(.01, 2);
this.tmpForce = new THREE.Vector3;
this.diff = new THREE.Vector3;
this.pins = [];
for( var i = 0; i <= this.SEGMENTS; i++ )
this.pins.push( i );
this.degree = 0;
this.wave = 0;
}
animatedProduct.prototype = {
createPlane: function( width, height ) {
return function(c, d) {
var e = ( c - .5 ) * width,
f = ( d + .5 ) * height,
g = 0;
return new THREE.Vector3( e, f, g )
}
},
satisfyConstraints: function( p1, p2, distance ) {
this.diff.subVectors( p2.position, p1.position );
var currentDist = this.diff.length();
if ( currentDist === 0 )
return; // prevents division by 0
this.diff.normalize();
var correction = this.diff.multiplyScalar( currentDist - distance );
var correctionHalf = correction.multiplyScalar( 0.5 );
p1.position.add( correctionHalf );
p2.position.sub( correctionHalf );
},
simulate: function( timestep_sq ) {
var b, c, d, e, f, g, h, i, j = this.clothGeometry.faces;
for (d = this.cloth.particles, b = 0, c = d.length; c > b; b++) {
e = d[b];
e.addForce(this.gravity);
e.integrate(timestep_sq);
}
for (f = this.cloth.constraints, c = f.length, b = 0; c > b; b++) {
g = f[b];
this.satisfyConstraints(g[0], g[1], g[2]);
}
for (d = this.cloth.particles, b = 0, c = d.length; c > b; b++) {
e = d[b];
e.position.x = e.original.x;
}
for (b = 0, c = this.pins.length; c > b; b++) {
var k = this.pins[ b ],
l = d[ k ];
l.position.y = l.original.y;
l.position.x = l.original.x;
l.position.z = l.position.z + this.wave;
}
if( this.degree <= 6 ) {
this.wave = Math.sin( this.degree ) * 6;
this.degree += 0.017 * 42;
}
else
this.wave = 0;
},
init: function() {
this.clothFunction = this.createPlane( this.size, this.size );
this.cloth = new Cloth( this.MASS, this.SEGMENTS, this.SEGMENTS, this.restDistance, this.DRAG, this.createPlane( this.size, this.size ) );
this.scene = new THREE.Scene;
this.camera = new THREE.PerspectiveCamera( 45, this.canvas.width / this.canvas.height, 1, 1e4 );
this.camera.position.y = 0;
this.camera.position.z = 1e3;
this.scene.add( this.camera );
this.light = new THREE.DirectionalLight( 16777215, 1 );
this.light.position.set( 20, -20, 100 );
this.scene.add( this.light );
THREE.ImageUtils.crossOrigin = "";
var texture = THREE.ImageUtils.loadTexture( this.image, {}, function() {
this.canvas.classList.add("play")
}.bind( this ) );
texture.flipY = !1;
texture.wrapS = texture.wrapT = THREE.RepeatWrapping;
texture.anisotropy = 16;
var b = new THREE.MeshPhongMaterial({
ambient: 16777215,
shininess: 20,
map: texture,
side: THREE.DoubleSide
});
this.clothGeometry = new THREE.ParametricGeometry( this.clothFunction, this.cloth.w, this.cloth.h );
this.clothGeometry.dynamic = !0;
this.clothGeometry.computeFaceNormals();
var c = {
texture: {
type: "t",
value: texture
}
},
d = "varying vec2 vUV;void main() {vUV = 0.75 * uv;vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );gl_Position = projectionMatrix * mvPosition;}",
e = "uniform sampler2D texture;varying vec2 vUV;vec4 pack_depth( const in float depth ) {const vec4 bit_shift = vec4( 256.0 * 256.0 * 256.0, 256.0 * 256.0, 256.0, 1.0 );const vec4 bit_mask = vec4( 0.0, 1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0 );vec4 res = fract( depth * bit_shift );res -= res.xxyz * bit_mask;return res;}void main() {vec4 pixel = texture2D( texture, vUV );if ( pixel.a < 0.5 ) discard;gl_FragData[ 0 ] = pack_depth( gl_FragCoord.z );}";
this.object = new THREE.Mesh( this.clothGeometry, b );
this.object.position.set( 0, 0, 0 );
this.scene.add( this.object );
this.object.customDepthMaterial = new THREE.ShaderMaterial({
uniforms: c,
vertexShader: d,
fragmentShader: e
});
this.renderer = new THREE.WebGLRenderer({
antialias: !0,
canvas: this.canvas
});
this.renderer.setSize( this.canvas.width, this.canvas.height );
this.renderer.setClearColor( 16777215, 1 );
this.renderer.autoClear = !1;
this.renderer.autoClearDepth = !1;
this.container.appendChild( this.renderer.domElement );
this.renderer.gammaInput = !0;
this.renderer.gammaOutput = !0;
this.canvas.addEventListener("mousedown", this.onClick.bind( this ), !1 );
for (var f = 0; 20 > f; f++) this.simulate(this.TIMESTEP_SQ);
this.play();
},
onClick: function(a) {
},
animate: function() {
this.animationFrame = window.requestAnimationFrame(this.animate.bind(this));
this.simulate(this.TIMESTEP_SQ);
this.render();
},
pause: function() {
window.cancelAnimationFrame( this.animationFrame );
},
play: function() {
this.scene ? this.animate() : this.init();
},
render: function() {
for ( var a = this.cloth.particles, b = 0, c = a.length; c > b; b++ )
this.clothGeometry.vertices[ b ].copy( a[ b ].position );
this.clothGeometry.computeFaceNormals();
this.clothGeometry.computeVertexNormals();
this.clothGeometry.normalsNeedUpdate = !0;
this.clothGeometry.verticesNeedUpdate = !0;
this.camera.lookAt( this.scene.position );
this.renderer.clear();
this.renderer.render( this.scene, this.camera );
},
stop: function() {
this.pause();
this.canvas.parentNode.removeChild( this.canvas );
}
};
var size = 700,
container = document.getElementById( "product-container" ),
image = "http://media.hermes.com/media/catalog/product/import/S/S01/S011/item/flat/hd/H001485S-17.jpg",
canvas = document.createElement( "canvas" );
canvas.width = canvas.height = 600 + 20,
canvas.id = "product",
container.appendChild( canvas ),
productAnimation = new animatedProduct( container, size, canvas, image );
productAnimation.play();
<script src="http://maksible.com/cloth/cloth_slower_v2/cloth/three.min.js"></script>
<body>
<div id="product-container"></div>
<script type="text/javascript" src="three.min.js"></script>
<script type="text/javascript" src="logic.js"></script>
</body>
Here is the solution with three.js but with different logic than yours. Hope it might be useful for you.
var size = 500;
var img = 'Image.jpg';
window.onload = function() {
createWGL();
render();
}
// render
//
function render() {
requestAnimationFrame( render );
if(window.mat)
mat.uniforms.time.value = now();
ctx.render( scn, cam );
}
// create renderer
//
function createWGL() {
// check desktop/mobile
window.desk = !(/Android|webOS|iPhone|iPad|BlackBerry|Windows Phone|Opera Mini|IEMobile|Mobile/i.test(navigator.userAgent));
window.ctx = new THREE.WebGLRenderer({antialias:window.desk});
ctx.setClearColor( 0xffffff );
ctx.setPixelRatio( window.devicePixelRatio );
ctx.setSize( size, size );
// camera
window.cam = new THREE.PerspectiveCamera( 90, 1, 1, 30 );
cam.position.z = 25;
// scene
window.scn = new THREE.Scene();
// canvas
window.cvs = createCanvas();
scn.add( cvs );
loadCanvasTexture( img );
// clear viewport
ctx.render( scn, cam );
document.body.appendChild( ctx.domElement );
}
// now
//
function now(){
return performance.now() * 0.001;
}
// load canvas texture
//
function loadCanvasTexture( path ) {
if(window.tex)
window.tex.dispose();
cvs.visible = false;
window.tex = new THREE.TextureLoader().load( path, function(){
cvs.visible = true;
});
window.tex.anisotropy = ctx.getMaxAnisotropy();
window.mat.uniforms.tex.value = window.tex;
}
// create canvas
//
function createCanvas() {
window.mat = new THREE.RawShaderMaterial({
uniforms: {
time: { value: now() },
tex: { value: null }
},
vertexShader: 'precision mediump float;precision mediump int;uniform mat4 modelViewMatrix;'+
'uniform mat4 projectionMatrix;attribute vec2 pos;uniform float time;varying vec2 uv;varying float amb;'+
'float d(float y){return cos(sin(time/2.)+time/2.+y/2.14)*sin(time+y/4.17)*(.5-y/40.)*1.5;}'+
'void main(){vec3 p=vec3( pos.x+sin(time/3.)*(.5-pos.y/40.), pos.y+sin(time)*(.5-pos.y/40.)/2., d(pos.y));amb=(d(pos.y-1.)-d(pos.y+1.))/4.;'+
'uv=vec2(pos.x/40.+.5,pos.y/40.+.5);gl_Position=projectionMatrix*modelViewMatrix*vec4(p,1.);}',
fragmentShader: 'precision mediump float;precision mediump int;uniform sampler2D tex;varying vec2 uv;varying float amb;'+
'void main(){vec4 col=texture2D(tex,uv)+amb;gl_FragColor=vec4(col.xyz,1.);}'
});
var d = 40,d2=~~(d/2),i,j,k,n,fi,v,m,z1=-1,z2;
fi = new Uint16Array( d * d * 6 );
v = new Int8Array( (d+1) * (d+1) * 2 );
for(j=0;j<=d;j++)
for(i=0;i<=d;i++) {
k = i + j*(d+1);
v[k*2] = i - d2;
v[k*2+1] = j - d2;
if(i<d&&j<d) {
n = (i + j*d) * 6;
fi[n] = k;
fi[n+1] = k + 1;
fi[n+2] = k + d + 1;
fi[n+3] = k + d + 1;
fi[n+4] = k + 1;
fi[n+5] = k + d + 2;
}
}
for(i=0,j=-1;i<fi.length;i++)
if(j<fi[i])
j = fi[i];
m = new THREE.Mesh( new THREE.BufferGeometry(), mat );
m.geometry.setIndex( new THREE.BufferAttribute( fi, 1 ));
m.geometry.addAttribute( 'pos', new THREE.BufferAttribute( v, 2 ));
return m;
}
just change your logic code with this and run.
cheers!

Cannon.JS make walls solid

I am making a go of three.js and cannon.js, but am stuck with being able to make walls solid, or anything solid that doesn't move and does hold the player back.
http://www.trepaning.com/3js/SEA3d/elvisCollideWalls.html
Here is the code I have thus far. Any insight appreciated. I prefer figuring stuff out on my own, but this one thing of making walls solid is holding me back at the moment, and I appreciate any info to get me over this hump.
if ( ! Detector.webgl ) Detector.addGetWebGLMessage();
var initScene;
var MARGIN = 10;
var MARGINSIDE = 0;
var WIDTH = window.innerWidth || ( 2 + 2 * MARGINSIDE );
//var WIDTH = window.innerWidth/3 || ( 2 + 2 * MARGINSIDE );
//var HEIGHT = window.innerHeight/3 || ( 2 + 2 * MARGIN );
var HEIGHT = window.innerHeight || ( 2 + 2 * MARGIN );
var SCREEN_WIDTH = WIDTH -2 * MARGINSIDE;
var SCREEN_HEIGHT = HEIGHT -2 * MARGIN;
var FAR = 10000;
var DAY = 0;
var stats, camera, scene, renderer;
var mesh, geometry;
var sunLight, pointLight, ambientLight, hemiLight;
var parameters
var clock = new THREE.Clock();
var inRender = true;
var inResize = false;
// cannon physics
var world;
var worldScale = 100;
var timeStep = 1/60;
var walls=[], balls=[], ballMeshes=[], boxes=[], boxMeshes=[];
var solidMaterial;
var playerMaterialPhy;
var playerRigid;
var playerPhysicsMesh;
var UNITSIZE = 250
var WALLHEIGHT = UNITSIZE / 3;
var map = [ // 1 2 3 4 5 6 7 8 9
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1,], // 0
[1, 1, 0, 0, 0, 0, 0, 1, 1, 1,], // 1
[1, 1, 0, 0, 2, 0, 0, 0, 0, 1,], // 2
[1, 0, 0, 1, 0, 2, 0, 0, 0, 1,], // 3
[1, 0, 0, 2, 0, 0, 2, 1, 0, 1,], // 4
[1, 0, 0, 0, 2, 0, 0, 0, 0, 1,], // 5
[1, 1, 1, 0, 0, 0, 0, 0, 1, 1,], // 6
[1, 1, 1, 0, 0, 0, 0, 0, 1, 1,], // 7
[1, 1, 1, 1, 1, 1, 0, 0, 1, 1,], // 8
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1,], // 9
], mapW = map.length, mapH = map[0].length;
// player
var loader;
var player;
var playerMaterial;
var playerMap = { map:undefined, normal:undefined};
var players=[];
var playerName = "LegoElvis";
var scaleFactor = 5;
var velocity = {x : 0, z : 0};
var playerControls = {
moveForward: false,
moveBackward: false,
moveLeft: false,
moveRight: false,
bodyOrientation: 0,
maxSpeed: 275,
maxReverseSpeed: -275,
frontAcceleration: 600,
backAcceleration: 600,
frontDecceleration: 600,
angularSpeed: 2.5,
speed: 0
};
var shadowConfig = {
Visible: false,
Near: 750,
Far: 4000,
Fov: 75,
Bias: -0.0002,
Darkness: 0.5,
Resolution:1024
};
var playerConfig = {
name: "",
loading: 0,
scale: 1,
CloneNumber: 30,
Clone: false
};
var LightConfig = {
Ambient: 0x554b3b,
Fog : 0x00283f
};
var MaterialConfig = {
shininess : 0,
specular: 1,
normalScaleX: 0,
normalScaleY: 0,
bias:0,
bumpScale: 2,
metal:false
};
var sky;
var skyCubeNight, skyCubeDay;
var skyShader;
initScene = function () {
// RENDERER
renderer = new THREE.WebGLRenderer( { clearColor: LightConfig.Fog, clearAlpha: 1, antialias: true } );
renderer.setSize( SCREEN_WIDTH, SCREEN_HEIGHT );
renderer.setClearColor( LightConfig.Fog, 1 );
renderer.domElement.style.position = "absolute";
document.getElementById( 'viewport' ).appendChild( renderer.domElement );
renderer.shadowMapEnabled = true;
renderer.shadowMapType = THREE.PCFSoftShadowMap;
renderer.gammaInput = true;
renderer.gammaOutput = true;
renderer.physicallyBasedShading = true;
// SCENE
scene = new THREE.Scene();
scene.fog = new THREE.Fog( LightConfig.Fog , 1000, FAR );
// CAMERA
camera = new THREE.PerspectiveCamera( 45, SCREEN_WIDTH / SCREEN_HEIGHT, 2, FAR );
camera.position.set( 50, 300, 350 );
// CAMERA CONTROL
controls = new THREE.OrbitControls( camera, renderer.domElement );
controls.center.set( 0, 0, 0 );
controls.keys = [];
controls.maxPolarAngle = toRad(90);
controls.userRotateSpeed = 1.8;
controls.zoomSpeed = 1.6;
controls.userPanSpeed = 0.8;
// GROUND
var mapGround = THREE.ImageUtils.loadTexture( "images/legoElvis.jpg" );
mapGround.anisotropy = renderer.getMaxAnisotropy();
mapGround.repeat.set( 100, 100 );
mapGround.wrapS = mapGround.wrapT = THREE.RepeatWrapping;
mapGround.magFilter = THREE.NearestFilter;
mapGround.format = THREE.RGBFormat;
var groundMaterial = new THREE.MeshPhongMaterial( { shininess: 10, ambient: 0x444444, color: 0xffffff, specular: 0xffffff, map: mapGround, metal: false } );
var planeGeometry = new THREE.PlaneGeometry( 100, 100 );
var ground = new THREE.Mesh( planeGeometry, groundMaterial );
ground.position.set( 0, 0, 0 );
ground.rotation.x = - Math.PI / 2;
ground.scale.set( 1000, 1000, 1000 );
ground.receiveShadow = true;
scene.add( ground );
initLights();
initPhysics();
loadSea3dModel();
stats = new Stats();
document.getElementById('my-stat').appendChild(stats.domElement);
// LISTENERS
window.addEventListener( 'resize', onWindowResize, false );
document.addEventListener( 'keydown', onKeyDown, false );
document.addEventListener( 'keyup', onKeyUp, false );
// TWEEN
parameters = { control: 0 };
animate();
}
//-----------------------------------------------------
// LIGHT
//-----------------------------------------------------
function initLights() {
var sunIntensity = 0.8;
var pointIntensity = 0.3;
var pointColor = 0xffffff;
var skyIntensity = 1;
ambientLight = new THREE.AmbientLight( LightConfig.Ambient );
scene.add( ambientLight );
hemiLight = new THREE.HemisphereLight( 0xffffff, 0xffffff, 0.6 );
hemiLight.color.setHSL( 0.63, 0.05, 0 );
hemiLight.groundColor.setHex( 0xe4c8a0 );
hemiLight.position.set( 0, 400, 0 );
scene.add( hemiLight );
pointLight = new THREE.PointLight( LightConfig.Moon, pointIntensity, 5000 );
pointLight.position.set( -1000, 0, -1000 );
scene.add( pointLight );
sunLight = new THREE.SpotLight( LightConfig.Sun, sunIntensity, 0, Math.PI/2, 1 );
sunLight.position.set( 1000, 2000, 1000 );
sunLight.castShadow = true;
sunLight.shadowCameraVisible = shadowConfig.Visible;
sunLight.shadowCameraNear = shadowConfig.Near;
sunLight.shadowCameraFar = shadowConfig.Far;
sunLight.shadowCameraFov = shadowConfig.Fov;
sunLight.shadowBias = shadowConfig.Bias;
sunLight.shadowDarkness = shadowConfig.Darkness * sunIntensity;
sunLight.shadowMapWidth = shadowConfig.Resolution;
sunLight.shadowMapHeight = shadowConfig.Resolution;
scene.add( sunLight );
}
function enableCascadeShadow() {
renderer.shadowMapCascade = true;
sunLight.shadowCascade = true;
sunLight.shadowCascadeCount = 3;
sunLight.shadowCascadeNearZ = [ -1.000, 0.995, 0.998 ];
sunLight.shadowCascadeFarZ = [ 0.995, 0.998, 1.000 ];
sunLight.shadowCascadeWidth = [ shadowConfig.Resolution, shadowConfig.Resolution, shadowConfig.Resolution ];
sunLight.shadowCascadeHeight = [ shadowConfig.Resolution, shadowConfig.Resolution, shadowConfig.Resolution ];
}
//-----------------------------------------------------
// RESIZE
//-----------------------------------------------------
function onWindowResize( event ) {
inResize = true;
//document.getElementById("viewport").style.background = '#222222';
SCREEN_WIDTH = window.innerWidth - 2 * MARGINSIDE;
SCREEN_HEIGHT = window.innerHeight - 2 * MARGIN;
camera.aspect = SCREEN_WIDTH / SCREEN_HEIGHT;
camera.updateProjectionMatrix();
renderer.setSize( SCREEN_WIDTH, SCREEN_HEIGHT );
}
//-----------------------------------------------------
// KEYBOARD
//-----------------------------------------------------
function onKeyDown ( event ) {
switch ( event.keyCode ) {
case 38: /*up*/
case 87: /*W*/
case 90: /*Z*/ playerControls.moveForward = true; break;
case 40: /*down*/
case 83: /*S*/ playerControls.moveBackward = true; break;
case 37: /*left*/
case 65: /*A*/
case 81: /*Q*/ playerControls.moveLeft = true; break;
case 39: /*right*/
case 68: /*D*/ playerControls.moveRight = true; break;
}
}
function onKeyUp ( event ) {
switch( event.keyCode ) {
case 38: /*up*/
case 87: /*W*/
case 90: /*Z*/ playerControls.moveForward = false; break;
case 40: /*down*/
case 83: /*S*/ playerControls.moveBackward = false; break;
case 37: /*left*/
case 65: /*A*/
case 81: /*Q*/ playerControls.moveLeft = false; break;
case 39: /*right*/
case 68: /*D*/ playerControls.moveRight = false; break;
}
};
//-----------------------------------------------------
// SEA3D
//-----------------------------------------------------
function loadSea3dModel() {
loader = new THREE.SEA3D( false );
//loader.matrixAutoUpdate = true;
//loader.invertCamera = true;
loader.onComplete = function( e ) {
player = loader.getMesh(playerName);
player.play("idle");
player.scale.set( playerConfig.scale*3, playerConfig.scale*3, -playerConfig.scale*3 );
scene.add( player );
creatPlayerPhysics();
};
//loader.load( 'folder/'+playerName+'.sea' );
loader.load( 'models/legoElvis.sea' );
}
// PLAYER ANIMATION
function updatePlayer(delta) {
if (playerControls.moveForward){
if (player.currentAnimation.name == "idle") player.play("walk");
} else if (playerControls.moveBackward){
if (player.currentAnimation.name == "idle") player.play("walk");
}
else {
if(player.currentAnimation.name == "walk") player.play("idle");
}
THREE.AnimationHandler.update( delta );
updatePlayerMove(delta);
}
// PLAYER MOVE
function updatePlayerMove( delta ) {
playerControls.maxReverseSpeed = -playerControls.maxSpeed;
if ( playerControls.moveForward ) playerControls.speed = THREE.Math.clamp( playerControls.speed + delta * playerControls.frontAcceleration, playerControls.maxReverseSpeed, playerControls.maxSpeed );
if ( playerControls.moveBackward ) playerControls.speed = THREE.Math.clamp( playerControls.speed - delta * playerControls.backAcceleration, playerControls.maxReverseSpeed, playerControls.maxSpeed );
// orientation based on controls
// (don't just stand while turning)
var dir = 1;
if ( playerControls.moveLeft ) {
playerControls.bodyOrientation += delta * playerControls.angularSpeed;
playerControls.speed = THREE.Math.clamp( playerControls.speed + dir * delta * playerControls.frontAcceleration, playerControls.maxReverseSpeed, playerControls.maxSpeed );
}
if ( playerControls.moveRight ) {
playerControls.bodyOrientation -= delta * playerControls.angularSpeed;
playerControls.speed = THREE.Math.clamp( playerControls.speed + dir * delta * playerControls.frontAcceleration, playerControls.maxReverseSpeed, playerControls.maxSpeed );
}
// speed decay
if ( ! ( playerControls.moveForward || playerControls.moveBackward ) ) {
if ( playerControls.speed > 0 ) {
var k = exponentialEaseOut( playerControls.speed / playerControls.maxSpeed );
playerControls.speed = THREE.Math.clamp( playerControls.speed - k * delta * playerControls.frontDecceleration, 0, playerControls.maxSpeed );
} else {
var k = exponentialEaseOut( playerControls.speed / playerControls.maxReverseSpeed );
playerControls.speed = THREE.Math.clamp( playerControls.speed + k * delta * playerControls.backAcceleration, playerControls.maxReverseSpeed, 0 );
}
}
// displacement
var forwardDelta = playerControls.speed * delta;
velocity.x = Math.sin( playerControls.bodyOrientation ) * forwardDelta;
velocity.z = Math.cos( playerControls.bodyOrientation ) * forwardDelta;
player.position.x += velocity.x;
player.position.z += velocity.z;
player.position.y = playerConfig.scale*scaleFactor;
// steering
player.rotation.y = playerControls.bodyOrientation;
if(controls){
//controls.target.set( player.position.x, player.position.y, player.position.z );
camera.position.x += velocity.x;
camera.position.z += velocity.z;
controls.center.set( player.position.x, player.position.y, player.position.z );
}
if(playerRigid){
//playerRigid.position.set(player.position.x, player.position.y+3, player.position.z );
playerRigid.position.set(player.position.x, player.position.y+80, player.position.z+15 );
playerRigid.quaternion.setFromAxisAngle(new CANNON.Vec3(0,1,0),player.rotation.y);
}
};
function exponentialEaseOut( k ) { return k === 1 ? 1 : - Math.pow( 2, - 10 * k ) + 1; };
//-----------------------------------------------------
// RENDER LOOP
//-----------------------------------------------------
function animate() {
requestAnimationFrame( animate );
if(inRender || inResize){
//if(isPad)PadTest();
//updateCamera();
var delta = clock.getDelta();
if(player!=null)updatePlayer(delta);
updatePhysics();
render();
stats.update();
}
inResize = false;
}
function render() {
TWEEN.update();
controls.update();
scene.fog.color.setHSL( 0.63, 0.05, parameters.control );
renderer.setClearColor( scene.fog.color, 1 );
pointLight.intensity = - parameters.control * 0.5 + 1;
hemiLight.color.setHSL( 0.63, 0.05, parameters.control )
sunLight.shadowDarkness = shadowConfig.Darkness * sunLight.intensity;
renderer.render( scene, camera );
}
function tell(s){
document.getElementById("debug").innerHTML = s;
}
//-----------------------------------------------------
// PHYSICS
//-----------------------------------------------------
function initPhysics() {
world = new CANNON.World();
world.quatNormalizeSkip = 0;
world.quatNormalizeFast = false;
var solver = new CANNON.GSSolver();
world.defaultContactMaterial.contactEquationStiffness = 1e9;
world.defaultContactMaterial.contactEquationRegularizationTime = 4;
solver.iterations = 3;
solver.tolerance = 0.1;
world.gravity.set(0,-9.82*worldScale,0);//world.gravity.set(0,-9.82,0); // m/s²
world.broadphase = new CANNON.NaiveBroadphase();
// Create a slippery material (friction coefficient = 0.0)
physicsMaterial = new CANNON.Material("slipperyMaterial");
solidMaterial = new CANNON.Material("solidMaterial");
playerMaterialPhy = new CANNON.Material("playerMat");
var physicsContactMaterial = new CANNON.ContactMaterial(physicsMaterial, physicsMaterial, 0.0, 0.3 );
var playerContactMaterial = new CANNON.ContactMaterial(playerMaterialPhy, playerMaterialPhy, 0.0, 0.3 );
var solidContactMaterial = new CANNON.ContactMaterial(solidMaterial, solidMaterial, 0.2, 0.6 );
world.addContactMaterial(physicsContactMaterial);
world.addContactMaterial(playerContactMaterial);
world.addContactMaterial(solidContactMaterial);
// Create infinie plane
var groundShape = new CANNON.Plane();
var groundBody = new CANNON.RigidBody(0,groundShape,physicsMaterial);
groundBody.quaternion.setFromAxisAngle(new CANNON.Vec3(1,0,0),-Math.PI/2);
world.add(groundBody);
createBoxeObject();
createBallObject();
}
function creatPlayerPhysics() {
if(playerPhysicsMesh){
scene.remove(playerPhysicsMesh);
playerPhysicsMesh.geometry.dispose();
}
if(playerRigid)world.remove(playerRigid);
//player body
var halfExtents = new CANNON.Vec3(0.5*worldScale,playerConfig.scale*80, 0.25*worldScale);
var playerShape = new CANNON.Box(halfExtents);
playerRigid = new CANNON.RigidBody(0,playerShape, playerMaterialPhy);
world.add(playerRigid);
playerRigid.linearDamping=0.01;
playerRigid.angularDamping=0.01;
var boxGeometry = new THREE.CubeGeometry(halfExtents.x*2,halfExtents.y*2,halfExtents.z*2);
playerPhysicsMesh = new THREE.Mesh( boxGeometry );
scene.add(playerPhysicsMesh);
playerPhysicsMesh.useQuaternion = true;
playerPhysicsMesh.castShadow = false;
playerPhysicsMesh.receiveShadow = false;
showPlayerPhysics();
}
function showPlayerPhysics() {
//if(OptionConfig.ShowPlayerHitBox)playerPhysicsMesh.visible = true;
//else playerPhysicsMesh.visible = true;
playerPhysicsMesh.visible = true;
}
function createBallObject() {
var s = worldScale;
var mat = new THREE.MeshLambertMaterial( { color: 0xdddddd } );
var radius;
var mass = 4;
var sphereShape;
for(var i=0; i<5; i++){
radius = (0.2+(Math.random()*0.8))*s;
sphereShape = new CANNON.Sphere(radius);
ballGeometry = new THREE.SphereGeometry(radius, 32, 32 );
var sphereBody = new CANNON.RigidBody(mass,sphereShape,physicsMaterial);
//sphereBody.linearDamping = 0.9;
var x = ((Math.random()-0.5)*20)*s;
var y = (1 + (Math.random()-0.5)*1)*s;
var z = ((Math.random()-0.5)*20)*s;
sphereBody.position.set(x,y,z);
sphereBody.linearDamping=0.03;
sphereBody.angularDamping=0.03;
world.add(sphereBody);
var ballMesh = new THREE.Mesh( ballGeometry, mat );
scene.add(ballMesh);
ballMesh.useQuaternion = true;
ballMesh.castShadow = true;
ballMesh.receiveShadow = true;
// add to array
balls.push(sphereBody);
ballMeshes.push(ballMesh);
}
}
function createBoxeObject() {
var s = worldScale;
var material = new THREE.MeshLambertMaterial( { color: 0x222222 } );
// Add boxes
var sx, xy, xz;
var halfExtents = new CANNON.Vec3(1*s,1*s,1*s);
var boxShape = new CANNON.Box(halfExtents);
var boxGeometry = new THREE.CubeGeometry(halfExtents.x*2,halfExtents.y*2,halfExtents.z*2);
for(var i=0; i<5; i++){
sx= 0.2+(Math.random()*0.8);
sy= 0.2+(Math.random()*0.8);
sz= 0.2+(Math.random()*0.8);
halfExtents = new CANNON.Vec3(sx*s,sy*s,sz*s);
boxShape = new CANNON.Box(halfExtents);
boxGeometry = new THREE.CubeGeometry(halfExtents.x*2,halfExtents.y*2,halfExtents.z*2);
var x = ((Math.random()-0.5)*20)*s;
var y = (1 + (Math.random()-0.5)*1)*s;
var z = ((Math.random()-0.5)*20)*s;
var boxBody = new CANNON.RigidBody(9,boxShape, solidMaterial);
var boxMesh = new THREE.Mesh( boxGeometry, material );
world.add(boxBody);
scene.add(boxMesh);
boxBody.position.set(x,y,z);
//boxMesh.position.set(x,y,z);
boxBody.quaternion.setFromAxisAngle(new CANNON.Vec3(0,0,0),toRad(Math.random()*360));
boxMesh.castShadow = true;
boxMesh.receiveShadow = true;
boxMesh.useQuaternion = true;
boxes.push(boxBody);
boxMeshes.push(boxMesh);
}
function createObstacle() {
obstacleMesh = new THREE.CubeGeometry(150, 50, 50)
obstacleMaterial = new THREE.MeshLambertMaterial( { color: 0x666666 } );
obstacleObject = new THREE.Mesh(obstacleMesh, obstacleMaterial);
obstacleObject.position.set(0, 26, 200);
obstacleObject.castShadow = true;
obstacleObject.receiveShadow = true;
scene.add(obstacleObject);
}
createObstacle();
function setupScene() {
var units = mapW;
// Geometry: walls
var cube = new THREE.CubeGeometry(UNITSIZE, WALLHEIGHT, UNITSIZE);
var materials = [
new THREE.MeshLambertMaterial({map: THREE.ImageUtils.loadTexture('images/legoElvisR.jpg')}), //wall 1
new THREE.MeshLambertMaterial({map: THREE.ImageUtils.loadTexture('images/legoElvisG.jpg')}), //wall 2
];
for (var i = 0; i < mapW; i++) {
for (var j = 0, m = map[i].length; j < m; j++) {
if (map[i][j]) {
var wall = new THREE.Mesh(cube, materials[map[i][j]-1]);
wall.position.x = (i - units/2) * UNITSIZE;
wall.position.y = WALLHEIGHT/2;
wall.position.z = (j - units/2) * UNITSIZE;
wall.castShadow = true;
wall.receiveShadow = true;
scene.add(wall);
}
}
}
}
setupScene();
// Add linked boxes
var size = 0.5*s;
var he = new CANNON.Vec3(size,size,size*0.1);
var boxShape = new CANNON.Box(he);
var mass = 0;
var space = 0.1*size;
var N=5, last;
var boxGeometry = new THREE.CubeGeometry(he.x*2,he.y*2,he.z*2);
for(var i=0; i<N; i++){
var boxbody = new CANNON.RigidBody(mass,boxShape, solidMaterial);
var boxMesh = new THREE.Mesh( boxGeometry, material );
boxbody.position.set(5*s,((N-i)*(size*2+2*space) + size*2+space)-150,0);
boxbody.linearDamping=0.01;
boxbody.angularDamping=0.01;
boxMesh.useQuaternion = true;
boxMesh.castShadow = true;
boxMesh.receiveShadow = true;
world.add(boxbody);
scene.add(boxMesh);
boxes.push(boxbody);
boxMeshes.push(boxMesh);
if(i!=0){
// Connect this body to the last one
var c1 = new CANNON.PointToPointConstraint(boxbody,new CANNON.Vec3(-size,size+space,0),last,new CANNON.Vec3(-size,-size-space,0));
var c2 = new CANNON.PointToPointConstraint(boxbody,new CANNON.Vec3(size,size+space,0),last,new CANNON.Vec3(size,-size-space,0));
world.addConstraint(c1);
world.addConstraint(c2);
} else {
mass=0.3;
}
last = boxbody;
}
}
function updatePhysics() {
if(!world) return;
world.step(timeStep);
// update player mesh test
if(playerRigid !== undefined){
playerRigid.position.copy(playerPhysicsMesh.position);
playerRigid.quaternion.copy(playerPhysicsMesh.quaternion);
}
// Update ball positions
for(var i=0; i<balls.length; i++){
balls[i].position.copy(ballMeshes[i].position);
balls[i].quaternion.copy(ballMeshes[i].quaternion);
}
// Update box positions
for(var i=0; i<boxes.length; i++){
boxes[i].position.copy(boxMeshes[i].position);
boxes[i].quaternion.copy(boxMeshes[i].quaternion);
}
}
//-----------------------------------------------------
// MATH
//-----------------------------------------------------
function toRad(Value) {
return Value * Math.PI / 180;
}
window.onload = initScene;
When you update your physics in updatePlayerMove, you set the position of the corresponding Cannon.js body. This body will never have a chance to update its position by itself since you override its position all the time.
Setting the position of bodies like this makes the physics unstable. You'll get large and buggy overlaps. And, of course, the player will be able to walk through walls.
Try controlling the player body via velocity instead. Cannon.js will then provide the response on the player for you, and the physics will become stable:
playerRigid.velocity.set(vx,vy,vz);

Alterative to merging geometries in Three.js

I'm trying to create a randomized terrain with a square base, which will be exported as an .STL (and 3d printed).
I'm having difficulties combining each seperate geometry into a single mesh. Ostensibly, my shape looks fine, however when I try to 3d Print the .STL, it's clear that there are some gaps in each individual geometry after they are merged.
Currently, I first create the top geometry and then the left, right, front, back, and bottom and finally merge these geometries into a single mesh.
My code right now is:
<!doctype html>
<html>
<head>
<meta charset="utf-8" />
<title>STL</title>
<style>
#container {
background: #000;
width: 800px;
height: 600px;
}
</style>
</head>
<body>
<input type="button" id="export" name="export" value="Export" />
<div id="container">
</div>
</body>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.5.1/jquery.min.js"></script>
<script src="js/three.min.js"></script>
<script src="js/loaders/STLLoader.js"></script>
<script src="js/exporters/STLExporter.js"></script>
<script src="js/Detector.js"></script>
<script src="js/libs/stats.min.js"></script>
<script src="js/ImprovedNoise.js"></script>
<script src="js/blob/Blob.js"></script>
<script src="js/filesaver/FileSaver.js"></script>
<script src="js/controls/FirstPersonControls.js"></script>
<script>
$(document).ready(function() {
var mouseX, mouseY = 0;
var WIDTH = 800,
HEIGHT = 600;
var VIEW_ANGLE = 45,
ASPECT = WIDTH / HEIGHT,
NEAR = 0.1,
FAR = 10000;
var container = $('#container');
var camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 1, 1000);
camera.position.z = 700;
var controls = new THREE.FirstPersonControls( camera );
controls.movementSpeed = 1000;
controls.lookSpeed = 0.1;
var exporter = new THREE.STLExporter();
var renderer = new THREE.WebGLRenderer();
var camera = new THREE.PerspectiveCamera( VIEW_ANGLE,
ASPECT,
NEAR,
FAR );
var scene = new THREE.Scene();
camera.position.z = 300;
renderer.setSize(WIDTH, HEIGHT);
var clock = new THREE.Clock();
animate();
container.append(renderer.domElement);
var sphereMaterial = new THREE.MeshLambertMaterial(
{
color: 0xCC0000
});
var worldWidth = 100, worldDepth = 100,
worldHalfWidth = worldWidth / 2, worldHalfDepth = worldDepth / 2;
var heightData = generateHeight( worldWidth, worldDepth );
camera.position.y = heightData[ 0] ;
var geometry = new THREE.PlaneGeometry( 300, 300, worldWidth - 1, worldDepth - 1 );
geometry.applyMatrix( new THREE.Matrix4().makeRotationX( - Math.PI / 2 ) );
for ( var i = 0, l = geometry.vertices.length; i < l; i ++ ) {
geometry.vertices[ i ].y = heightData[ i ] * 2;
}
var leftGeometry = new THREE.PlaneGeometry(300, 1, worldWidth - 1, worldDepth - 1 );
for( var i = 0; i < worldWidth; i++ ) {
for( var j = 0; j < worldDepth; j++ ) {
var index = j * worldWidth + i;
if ( j == worldDepth-1 ) {
leftGeometry.vertices[index].y = geometry.vertices[index].y +1;
}
}
}
var rightGeometry = new THREE.PlaneGeometry(300, 1, worldWidth - 1, worldDepth - 1 );
for( var i = 0; i < worldWidth; i++ ) {
for( var j = 0; j < worldDepth; j++ ) {
var index = j * worldWidth + i;
if ( j == 0 ) {
rightGeometry.vertices[index].y = geometry.vertices[index].y + 1;
}
}
}
var topGeometry = new THREE.PlaneGeometry(1, 300, worldWidth - 1, worldDepth - 1 );
topGeometry.applyMatrix( new THREE.Matrix4().makeRotationX( - Math.PI / 2 ) );
for( var i = 0; i < worldWidth; i++ ) {
for( var j = 0; j < worldDepth; j++ ) {
var index = j * worldWidth + i;
if ( i == 0 ) {
topGeometry.vertices[index].y = geometry.vertices[index].y+1;
}
}
}
var bottomGeometry = new THREE.PlaneGeometry(1, 300, worldWidth - 1, worldDepth - 1 );
bottomGeometry.applyMatrix( new THREE.Matrix4().makeRotationX( - Math.PI / 2 ) );
for( var i = 0; i < worldWidth; i++ ) {
for( var j = 0; j < worldDepth; j++ ) {
var index = j * worldWidth + i;
if ( i == worldWidth-1 ) {
bottomGeometry.vertices[index].y = geometry.vertices[index].y+1;
}
}
}
var baseGeometry = new THREE.PlaneGeometry(300, 300, worldWidth - 1, worldDepth - 1 );
baseGeometry.applyMatrix( new THREE.Matrix4().makeRotationX( - Math.PI / 2 ) );
// ------------------------------
var combined = new THREE.Geometry();
var meshA = new THREE.Mesh( geometry, new THREE.MeshNormalMaterial() );
var meshB = new THREE.Mesh( leftGeometry, new THREE.MeshNormalMaterial() );
var meshC = new THREE.Mesh( rightGeometry, new THREE.MeshNormalMaterial() );
var meshD = new THREE.Mesh( topGeometry, new THREE.MeshNormalMaterial() );
var meshE = new THREE.Mesh( bottomGeometry, new THREE.MeshNormalMaterial() );
var meshF = new THREE.Mesh( baseGeometry, new THREE.MeshNormalMaterial() );
meshB.position.z = worldHalfWidth+100;
meshB.position.y = 0;
meshC.position.y = 0;
meshC.position.z = -worldHalfWidth-100;
meshD.position.x = -worldHalfWidth-99;
meshE.position.x = worldHalfWidth+99;
THREE.GeometryUtils.merge(combined, meshA);
THREE.GeometryUtils.merge(combined, meshB);
THREE.GeometryUtils.merge(combined, meshC);
THREE.GeometryUtils.merge(combined, meshD);
THREE.GeometryUtils.merge(combined, meshE);
THREE.GeometryUtils.merge(combined, meshF);
var out = new THREE.Mesh( combined, new THREE.MeshBasicMaterial({
wireframe: true,
color: 'white'
}));
scene.add(out);
scene.add(camera);
var pointLight = new THREE.PointLight( 0xFFFFFF );
pointLight.position.x = 10;
pointLight.position.y = 50;
pointLight.position.z = 130;
scene.add(pointLight);
renderer.render(scene, camera);
function generateHeight( width, height ) {
var size = width * height, data = new Float32Array( size ),
perlin = new ImprovedNoise(), quality = 1, z = Math.random() * 100;
for ( var i = 0; i < size; i ++ ) {
data[ i ] = 0
}
for ( var j = 0; j < 4; j ++ ) {
for ( var i = 0; i < size; i ++ ) {
var x = i % width, y = ~~ ( i / width );
data[ i ] += Math.abs( perlin.noise( x / quality, y / quality, z ) * quality * 1.75 );
}
quality *= 5;
}
return data;
}
function animate() {
requestAnimationFrame( animate );
render();
}
function render() {
controls.update( clock.getDelta() );
renderer.render( scene, camera );
camera.position.z = ( mouseX - camera.position.x ) * .6;
}
$("#export").click(function(){
var out = exporter.exportScene(scene);
var blob = new Blob([out], {type: 'text/plain'});
saveAs(blob, 'please work.stl');
});
$("#container").mousemove(function(event) {
mouseX = event.pageX;
mouseY = event.pageY;
});
});
</script>
</html>
My questions is: Is there another way to create this type of shape, other than using the GeometryUtils.merge function? Currently, the output shape cannot be 3d printed, and I'm wondering if it's because after the shapes are merged, the final geometry contains gaps. I'm not sure how to remedy this issue.

How to solve this loop and present the cones in an order?

var lc_relationship= null;
var container, nSize = 100;
var camera, scene, renderer;
var scale = 10, scale1 = 100; N=50, cubeRotSpd=0;
var arr= [];
var width = window.innerWidth, height = window.innerHeight;
function generateData()
{
var aSensor1 = [],
aSensor2 = [],
aSensor3 = [];
lc_relationship = {
"sensor1":[],
"sensor2":[],
"sensor3":[]
}
for(i=1; i<=nSize; i++)
{
aSensor1.push(i);
aSensor2.push(i);
aSensor3.push(i);
}
for(n=0; n<nSize; n++)
{
var pos1 = Math.floor(Math.random() * (nSize-n));
var pos2 = Math.floor(Math.random() * (nSize-n));
var pos3 = Math.floor(Math.random() * (nSize-n));
var int1 = aSensor1[pos1]; aSensor1.splice(pos1,1);
var int2 = aSensor2[pos2]; aSensor2.splice(pos2,1);
var int3 = aSensor3[pos3]; aSensor3.splice(pos3,1);
lc_relationship.sensor1[int1-1] =
{
"ObjectID" : "sens1_" + rightPad(int1),
"Geometry" : getGeometry(),
"Parent":null,
"child": "sens2_" + rightPad(int2),
"z_cordinate": -5
}
lc_relationship.sensor2[int2-1] =
{
"ObjectID" : "sens2_" + rightPad(int2),
"Geometry" : getGeometry(),
"Parent":"sens1_" + rightPad(int1),
"child": "sens3_" + rightPad(int3),
"z_cordinate": 0
}
lc_relationship.sensor3[int3-1] =
{
"ObjectID" : "sens3_" + rightPad(int3),
"Geometry" : getGeometry(),
"Parent":"sens2_" + rightPad(int2),
"child": null,
"z_cordinate": 5
}
}
}
function rightPad(number)
{
var tmpStr = number.toString();
return ("000" + tmpStr).substring(tmpStr.length, tmpStr.length+3);
}
function getGeometry()
{
var geo = new THREE.Geometry();
geo.vertices.push(new THREE.Vertex(
new THREE.Vector3( 0, 0, 0)));
geo.vertices.push(new THREE.Vertex(
new THREE.Vector3( -0.5, 0.5, 1)));
geo.vertices.push(new THREE.Vertex(
new THREE.Vector3( 0.5, 0.5, 1)));
geo.vertices.push(new THREE.Vertex(
new THREE.Vector3( -0.5, -0.5, 1)));
geo.vertices.push(new THREE.Vertex(
new THREE.Vector3( 0.5,-0.5, 1)));
geo.faces.push( new THREE.Face3(0,1,2));
geo.faces.push( new THREE.Face3(2,1,4));
geo.faces.push( new THREE.Face3(1,3,4));
geo.faces.push( new THREE.Face3(4,3,0));
geo.faces.push( new THREE.Face3(3,1,0));
geo.faces.push( new THREE.Face3(0,2,4));
geo.computeFaceNormals();
/* cone = new THREE.Mesh(geo, meshMaterial);
cone.doubleSided = true;
cone.overdraw = true;*/
return geo;
}
function posgeo()
{ generateData();
//var jsonText = JSON.stringify(lc_relationship);
//document.getElementById("output").innerHTML=jsonText;
//document.getElementById("test").innerHTML=lc_relationship.sensor1[0].z_cordinate;
init();
animate();
}
function init()
{
container = document.getElementById("output");
camera = new THREE.PerspectiveCamera( 45, width / height, 0.1, 1000 );
camera.position.y = 0;
camera.position.z = 45;
camera.lookAt(new THREE.Vector3(0, 0, 0));
scene = new THREE.Scene();
scene.add(camera);
renderer = new THREE.WebGLRenderer(/*{antialias:true}*/);
renderer.setClearColorHex(0xffffff, 1);
renderer.setSize( width, height );
var meshmaterial = new THREE.MeshLambertMaterial( { color: 0x0000CC, opacity: 0.3, depthWrite: false, depthTest: false });
I'm having whole problem at this loop, Can someone help me to fix this? The Loop is here:
for ( var i = 0; i <nSize; i++)
for ( var j = -5; j < 5; j++)
for ( var k = -5; k < 5; k++)
{
var cone1 = new THREE.MESH(lc_relationship.sensor1[i].Geometry,meshMaterial);
cone1.doubleSided = true;
cone1.overdraw = true;
scene.add(cone1);
var cone2 = new THREE.MESH(lc_relationship.sensor2[i].Geometry,meshMaterial);
cone2.doubleSided = true;
cone2.overdraw = true;
scene.add(cone2);
var cone3 = new THREE.MESH(lc_relationship.sensor3[i].Geometry,meshMaterial);
cone3.doubleSided = true;
cone3.overdraw = true;
scene.add(cone3);
cone1.position.set(2*k, 2*j,lc_relationship.sensor1[i].z_cordinate);
cone2.position.set(2*k, 2*j,lc_relationship.sensor2[i].z_cordinate);
cone3.position.set(2*k, 2*j,lc_relationship.sensor3[i].z_cordinate);
}
All I want to dispay cones like image below :
and the remaining Code:
var light = new THREE.DirectionalLight(0xffffff, 0.6);
light.position.y = 1;
light.position.x = 1;
light.position.z = 1;
scene.add(light);
light = new THREE.DirectionalLight(0xffffff, 0.6);
light.position.y = -1;
light.position.x = -1;
light.position.z = -1;
scene.add(light);
light = new THREE.DirectionalLight(0xffffff, 0.6);
light.position.y = 1;
light.position.x = 0;
light.position.z = 0;
scene.add(light);
container.appendChild( renderer.domElement );
}
function animate()
{
requestAnimationFrame( animate );
render();
}
function render()
{
renderer.render(scene, camera);
}
Can Some help to solve this issue. This task is really sitting on head all the time :(
You can do it with a single loop, by calculating j and k from j instead of adding two more loops:
for ( var i = 0; i <nSize; i++)
{
var k = i%10,
j = (i-k)/10;
j = j*2 - 10; // You may need to adjust this "10",
k = k*2 - 10; // may be "9", so the layers get centered.
//console.log(j,k)
var cone1 = new THREE.MESH(lc_relationship.sensor1[i].Geometry,meshMaterial);
cone1.doubleSided = true;
cone1.overdraw = true;
scene.add(cone1);
var cone2 = new THREE.MESH(lc_relationship.sensor2[i].Geometry,meshMaterial);
cone2.doubleSided = true;
cone2.overdraw = true;
scene.add(cone2);
var cone3 = new THREE.MESH(lc_relationship.sensor3[i].Geometry,meshMaterial);
cone3.doubleSided = true;
cone3.overdraw = true;
scene.add(cone3);
cone1.position.set(j, k, lc_relationship.sensor1[i].z_cordinate);
cone2.position.set(j, k, lc_relationship.sensor2[i].z_cordinate);
cone3.position.set(j, k, lc_relationship.sensor3[i].z_cordinate);
}

Categories