The company needs to realize the visualization of floors and equipment when it works in malls, fire protection, electricity and other projects. In the past, the whole model was created by other modeling tools, and then loaded into the scene by using the 3.js loader. However, such loading has defects, such as the inability to assign attributes to the elements of the model, the inability to single click on elements, rendering monotonous, and so on. So this time I refer to some information, not using model inversion, using three. JS to build the scene completely, the code is a bit rough, no wonder.
1. Create floors
Floor is a similar box, with top and bottom and side, but not necessarily a regular box. So I abandoned the usual way of BoxGeometry and used the form of vertex + surface to create arbitrary polygonal floor. The bottom coordinates of polygons are known, and the top coordinates are obtained by the bottom coordinates and height. Through Earcut, the triangles of bottom and top and side can be calculated. The surface can be obtained directly by the ordinal number of coordinates, thus creating a general Geometry.
Floor.prototype.getGeometry = function(points,height){
var topPoints = [];
for(var i=0;i<points.length;i++){
var vertice = points[i];
topPoints.push([vertice[0],vertice[1]+height,vertice[2]]);
}
var totalPoints = points.concat(topPoints);
Var vertices = []; // all vertices
for(var i=0;i<totalPoints.length;i++){
vertices.push(new THREE.Vector3(totalPoints[i][0],totalPoints[i][1],totalPoints[i][2]))
}
var length = points.length;
var faces = [];
For (var J = 0; J < length; J +) {// side generation triangle
if(j!=length-1){
faces.push(new THREE.Face3(j,j+1,length+j+1));
faces.push(new THREE.Face3(length+j+1,length+j,j));
}else{
faces.push(new THREE.Face3(j,0,length));
faces.push(new THREE.Face3(length,length+j,j));
}
}
var data=[];
for(var i=0;i<length;i++){
data.push(points[i][0],points[i][2]);
}
var triangles = Earcut.triangulate(data);
if(triangles && triangles.length != 0){
for(var i=0;i<triangles.length;i++){
var tlength = triangles.length;
if(i%3==0 && i < tlength-2){
Faces. push (new THREE. Face3 (triangles [i], triangles [i + 1], triangles [i + 2]); // bottom triangles
Faces. push (new THREE. Face3 (triangles [i] + length, triangles [i + 1] + length, triangles [i + 2] + length);//top triangle
}
}
}
var geometry = new THREE.Geometry();
geometry.vertices = vertices;
geometry.faces = faces;
Geometry. computeFaceNormals ();// Automated calculation of normal vectors
return geometry;
}
Effect:
2. Create walls
I used BoxGeometry for the wall, the holes of windows and doors on the wall. We can use the difference set function in ThreeBSP library to subtract the model.
Floor.prototype.addWall = function(size,position,rotation,holes){
var geometry = new THREE.BoxGeometry(size[0], size[1], size[2]);
var materials = new THREE.MeshLambertMaterial({color: 0xb0cee0,side:THREE.DoubleSide})
var result = new THREE.Mesh(geometry,materials);
if(holes){
result = cube;
for(var i=0;i<holes.length;i++){
var totalBSP = new ThreeBSP(result);
var hole = holes[i];
var holeGeometry = new THREE.BoxGeometry(hole.size[0], hole.size[1], hole.size[2]);
var holeCube = new THREE.Mesh( holeGeometry);
holeCube.position.x = hole.position[0];
holeCube.position.y = hole.position[1] + hole.size[1]/2;
holeCube.position.z = hole.position[2];
var clipBSP = new ThreeBSP(holeCube);
var resultBSP = totalBSP.subtract(clipBSP);
result = resultBSP.toMesh();
}
result.material = materials;
}
This. container. add (result); // add padding
}
Effect:
3. door frame
Before adding doors, I added doorframes to make them more vivid. First use the wall to subtract the hole in the door frame, and then add the door frame subtracted from the door frame, similar to the front, the specific code is not put.
Effect:
4. Doors, windows, mainframe, display screen, tables
Doors, windows, mainframes, display screens, tables are all in the form of Box Geometry, and then texture the corresponding surface, similar to the front, the effect is as follows:
5. potted plants
Potted pots can use Cylinder Buffer Geometry to create a platform with a top larger than the bottom. Potted leaves are displayed from different angles using multiple PlaneGeometries with plant textures. The code is as follows:
// potted plant
Floor.prototype.addPlant = function(position,scale){
var plant = new THREE.Object3D();
var geometry = new THREE.CylinderBufferGeometry( 0.15, 0.1, 0.4, 22 );
var material = new THREE.MeshLambertMaterial( {color: 0xffffff} );
var cylinder = new THREE.Mesh( geometry, material );
cylinder.position.x = 0;
cylinder.position.y = 0.2;
cylinder.position.z = 0;
plant.add( cylinder );
var leafTexture = new THREE.TextureLoader().load('meeting/plant.png');
var leafMaterial = new THREE.MeshBasicMaterial({map:leafTexture,side:THREE.DoubleSide,transparent:true});
var geom = new THREE.PlaneGeometry(0.4, 0.8);
for(var i=0;i<4;i++){
var leaf = new THREE.Mesh( geom, leafMaterial );
leaf.position.y = 0.8;
leaf.rotation.y = -Math.PI/(i+1);
plant.add(leaf);
}
plant.position.x = position[0];
plant.position.y = position[1];
plant.position.z = position[2];
this.container.add(plant);
}
Effectiveness (very rough):
6. chairs
The chair model is a bit complicated, because it almost gave up creating chairs with three, but it has confidence and courage to see a companion minicity created entirely with three. So: 4 chair legs positioning + rotation, chair surface, 2 backrest legs positioning + rotation, backrest positioning + rotation, and finally created, the code is too ugly to go on. Effect:
7. Open-door animation
Open-door animation I used the TWEEN library, Tween. JS is a JS resource that contains a variety of classical animation algorithms, dynamically changing the value of the door in the z-axis direction.
if(status == "close"){
status = "open";
var desRotation = Math.PI/2;
new TWEEN.Tween(door.rotation).to({
y: desRotation
}, 10000).easing(TWEEN.Easing.Elastic.Out).onComplete(function(){
}).start();
}else{
status = "close";
new TWEEN.Tween(door.rotation).to({
y: 0
}, 10000).easing(TWEEN.Easing.Elastic.Out).onComplete(function(){
}).start();
}
Effect:
8. Walking animation
I use the animation module of three to import the FBX model with animation. The production of model animation is very complicated. We can download it on the network. Play the animation after importing the animation.
var Mixers = [];
var animation;
var walkingMan;
var loader = new THREE.FBXLoader();
loader.load('file/walkingman.fbx', function ( object ) { //Samba Dancing.fbx
object.mixer = new THREE.AnimationMixer( object );
Mixers.push( object.mixer ); //AnimationMixer
animation = object.mixer.clipAction( object.animations[ 0 ] ); //AnimationAction AnimationClip
walkingMan = object;
walkingMan.scale.x = walkingMan.scale.y = walkingMan.scale.z = 0.8;
walkingMan.position.x = firstPoint[0];
walkingMan.position.y = firstPoint[1];
walkingMan.position.z = firstPoint[2];
WalkingMan. rotation. y = rotation; // Angle is calculated based on the current point and the next point
scene.add( walkingMan );
animation.play();
});
function updateWalkingMan(){
if ( Mixers.length > 0 ) {
for ( var i = 0; i < Mixers.length; i ++ ) {
Mixers[ i ].update(clock.getDelta());//clock.getDelta()
}
}
}
function render() {
updateWalkingMan();
requestAnimationFrame(render);
renderer.render(scene, camera);
}
Effect:
While playing animation, we can change the position and angle of the character model to achieve the effect of walking in the scene.
The conference room modelling is over. It’s also an exploration. The follow-up goal is to encapsulate commonly used models, establish user interaction modeling methods in the web, and build more standard and fast indoor scenes.
The above is the whole content of this article. I hope it will be helpful to everyone’s study, and I hope you will support developpaer more.
0 comentarios:
Publicar un comentario