mirror of
https://github.com/ToxicCrack/PrintABrick.git
synced 2025-05-21 06:30:10 -07:00
Improve ModelViewer
This commit is contained in:
parent
00e70875ff
commit
61caac6f55
@ -1,85 +1,215 @@
|
||||
ModelViewer = function() {
|
||||
var container;
|
||||
var camera, cameraTarget, scene, renderer, controls, object;
|
||||
var width, height;
|
||||
var ModelViewer = function($container) {
|
||||
var $this = this;
|
||||
this.container = $container;
|
||||
|
||||
this.initScene = function($container) {
|
||||
width = parseFloat($container.width());
|
||||
height = parseFloat($container.height());
|
||||
this.camera = null;
|
||||
this.scene = null;
|
||||
this.renderer = null;
|
||||
this.controls = null;
|
||||
this.object = null;
|
||||
this.width = parseFloat(this.container.width());
|
||||
this.height = parseFloat(this.container.height());
|
||||
this.visible = true;
|
||||
this.scale = 1;
|
||||
|
||||
camera = new THREE.PerspectiveCamera(45, width/height, 0.1, 1000);
|
||||
camera.position.set(-2, 2, 0.8);
|
||||
camera.lookAt(new THREE.Vector3(0, 3, 0));
|
||||
this.initScene();
|
||||
|
||||
scene = new THREE.Scene();
|
||||
scene.fog = new THREE.FogExp2(0x000000, 0.001);
|
||||
function renderLoop() {
|
||||
requestAnimationFrame( renderLoop );
|
||||
$this.render();
|
||||
}
|
||||
|
||||
// var grid = new THREE.GridHelper( 30, 70 );
|
||||
// // grid.position.set(30/70,-0.5,30/70);
|
||||
// scene.add( grid );
|
||||
renderLoop();
|
||||
};
|
||||
|
||||
// Lights
|
||||
ModelViewer.prototype.initScene = function() {
|
||||
|
||||
light = new THREE.DirectionalLight( 0xffffff );
|
||||
light.position.set( 1, 1, 1 );
|
||||
scene.add( light );
|
||||
this.scene = new THREE.Scene();
|
||||
|
||||
light = new THREE.DirectionalLight( 0x002288 );
|
||||
light.position.set( -1, -1, -1 );
|
||||
scene.add( light );
|
||||
this.camera = new THREE.PerspectiveCamera(45, this.width / this.height, 1, 1000);
|
||||
this.camera.position.z = 8;
|
||||
this.camera.position.y = -5;
|
||||
this.camera.position.x = 3;
|
||||
this.camera.up = new THREE.Vector3(0, 0, 1);
|
||||
|
||||
this.reflectCamera = new THREE.CubeCamera(1, 50, 200);
|
||||
this.scene.add(this.reflectCamera);
|
||||
|
||||
var material = new THREE.MeshPhongMaterial({
|
||||
color: 0xffffff,
|
||||
emissive: 0xffffff,
|
||||
shading: THREE.SmoothShading,
|
||||
fog: false,
|
||||
side: THREE.BackSide
|
||||
});
|
||||
|
||||
var skybox = new THREE.Mesh(new THREE.CubeGeometry(100, 100, 100), material);
|
||||
skybox.name = 'skybox';
|
||||
this.scene.add(skybox);
|
||||
|
||||
var groundPlaneMaterial = new THREE.MeshPhongMaterial({
|
||||
color: 0x888888,
|
||||
wireframe: false,
|
||||
transparent: true,
|
||||
opacity: 0.25,
|
||||
// fog: true,
|
||||
// specular: 0x999999,
|
||||
envMap: this.reflectCamera.renderTarget
|
||||
});
|
||||
var x = 80;
|
||||
var y = 80;
|
||||
var division_x = Math.floor(x / 2);
|
||||
var division_y = Math.floor(y / 2);
|
||||
|
||||
this.plane = new THREE.Mesh(new THREE.PlaneGeometry(x, y, division_x, division_y), groundPlaneMaterial);
|
||||
this.plane.name = 'plane';
|
||||
this.plane.receiveShadow = true;
|
||||
this.scene.add(this.plane);
|
||||
|
||||
this.grid = new THREE.GridHelper( 80, 100, 0xEEEEEE,0xEEEEEE);
|
||||
this.grid.rotation.x = Math.PI/2;
|
||||
|
||||
this.scene.add(this.grid);
|
||||
|
||||
|
||||
scene.add( new THREE.AmbientLight( 0xf0f0f0 ));
|
||||
scene.background = new THREE.Color( 0x000000 );
|
||||
// this.wirePlane = new THREE.Mesh(new THREE.PlaneGeometry(x, y, division_x, division_y), new THREE.MeshPhongMaterial({
|
||||
// emissive: 0xEEEEEE,
|
||||
// color: 0x000000,
|
||||
// wireframe: true,
|
||||
// wireframeLinewidth: 2
|
||||
// }));
|
||||
// this.wirePlane.name = 'planewire';
|
||||
// this.wirePlane.receiveShadow = true;
|
||||
// this.wirePlane.position.z = this.plane.position.z + .01;
|
||||
// this.scene.add(this.wirePlane);
|
||||
|
||||
// renderer
|
||||
renderer = new THREE.WebGLRenderer();
|
||||
renderer.setClearColor( scene.fog.color );
|
||||
renderer.setPixelRatio( window.devicePixelRatio );
|
||||
renderer.setSize( width, height );
|
||||
renderer.gammaInput = true;
|
||||
renderer.gammaOutput = true;
|
||||
renderer.shadowMap.enabled = true;
|
||||
renderer.shadowMap.renderReverseSided = false;
|
||||
this.renderer = new THREE.WebGLRenderer();
|
||||
|
||||
$container.append(renderer.domElement);
|
||||
this.renderer.setSize(this.width, this.height);
|
||||
|
||||
controls = new THREE.OrbitControls( camera, renderer.domElement );
|
||||
controls.addEventListener( 'change', this.render ); // add this only if there is no animation loop (requestAnimationFrame)
|
||||
// controls.enableDamping = true;
|
||||
// controls.dampingFactor = 0.25;
|
||||
controls.enableZoom = true;
|
||||
};
|
||||
this.container.append(this.renderer.domElement);
|
||||
|
||||
this.loadStl = function(model) {
|
||||
var loader = new THREE.STLLoader();
|
||||
loader.load(model, function (geometry) {
|
||||
var material = new THREE.MeshPhongMaterial({color: 0xaaaaaa, shininess:200, specular: 0x333333, shading: THREE.FlatShading});
|
||||
|
||||
var mesh = new THREE.Mesh(geometry, material);
|
||||
this.scene.fog = new THREE.FogExp2(0xcacaca, 0.9);
|
||||
|
||||
mesh.geometry.computeBoundingBox();
|
||||
var positionY = (mesh.geometry.boundingBox.max.y + mesh.geometry.boundingBox.min.y)/2;
|
||||
// // Light
|
||||
this.spotLight = new THREE.SpotLight(0xffffff, 0.9, 0);
|
||||
this.spotLight.position.set(-70, 100, 100);
|
||||
this.spotLight.castShadow = false;
|
||||
this.scene.add(this.spotLight);
|
||||
|
||||
// mesh.position.set(0, positionY, 0);
|
||||
mesh.rotation.set(Math.PI, 0, 0);
|
||||
mesh.castShadow = true;
|
||||
mesh.receiveShadow = true;
|
||||
scene.add(mesh);
|
||||
|
||||
renderer.render(scene, camera);
|
||||
});
|
||||
};
|
||||
this.bottomSpotLight = new THREE.SpotLight(0xffffff, 0.3, 0);
|
||||
this.bottomSpotLight.position.set(70, -100, -100);
|
||||
this.bottomSpotLight.castShadow = false;
|
||||
this.scene.add(this.bottomSpotLight);
|
||||
|
||||
this.animate = function() {
|
||||
|
||||
requestAnimationFrame( this.animate );
|
||||
this.render();
|
||||
};
|
||||
this.pointLight = new THREE.PointLight(0xffaaff, 0.9, 0);
|
||||
this.pointLight.position.set(32, -39, 35);
|
||||
this.pointLight.castShadow = true;
|
||||
this.scene.add(this.pointLight);
|
||||
|
||||
this.render = function() {
|
||||
this.renderer.shadowMap.enabled = true;
|
||||
this.renderer.shadowMap.renderReverseSided = false;
|
||||
|
||||
renderer.render(scene, camera);
|
||||
// $container.append(this.renderer.domElement);
|
||||
|
||||
};
|
||||
this.controls = new THREE.OrbitControls( this.camera, this.renderer.domElement );
|
||||
this.controls.enableZoom = true;
|
||||
};
|
||||
|
||||
ModelViewer.prototype.addModel = function(geometry) {
|
||||
var material = new THREE.MeshPhongMaterial({
|
||||
color: 0x136FC3,
|
||||
specular: 0x0D0D0D,
|
||||
shading: THREE.SmoothShading,
|
||||
shininess: 150,
|
||||
fog: false,
|
||||
side: THREE.DoubleSide,
|
||||
// wireframe: true,
|
||||
});
|
||||
|
||||
geometry.center();
|
||||
var mesh = new THREE.Mesh(geometry, material);
|
||||
|
||||
mesh.scale.set(this.scale, this.scale, this.scale);
|
||||
|
||||
mesh.geometry.computeFaceNormals();
|
||||
mesh.geometry.computeVertexNormals();
|
||||
mesh.rotation.set(-Math.PI/2,0, 0);
|
||||
mesh.geometry.computeBoundingBox();
|
||||
|
||||
mesh.castShadow = true;
|
||||
// mesh.receiveShadow = true;
|
||||
|
||||
var dims = mesh.geometry.boundingBox.max.clone().sub(mesh.geometry.boundingBox.min);
|
||||
|
||||
maxDim = Math.max(Math.max(dims.x, dims.y), dims.z);
|
||||
|
||||
mesh.position.x = -(mesh.geometry.boundingBox.min.x + mesh.geometry.boundingBox.max.x) / 2 * this.scale;
|
||||
mesh.position.z = -(mesh.geometry.boundingBox.min.y + mesh.geometry.boundingBox.max.y) / 2 * this.scale;
|
||||
mesh.position.y = -mesh.geometry.boundingBox.min.z * this.scale;
|
||||
|
||||
var positionY = (mesh.geometry.boundingBox.max.z + mesh.geometry.boundingBox.min.z)/2 * this.scale;
|
||||
var positionZ = (mesh.geometry.boundingBox.max.y - mesh.geometry.boundingBox.min.y)/2 * this.scale;
|
||||
|
||||
mesh.position.set(0, positionY, positionZ);
|
||||
|
||||
// this.scene.face_count = mesh.geometry.faces.length;
|
||||
this.scene.add(mesh);
|
||||
|
||||
this.centerCamera(mesh);
|
||||
};
|
||||
|
||||
ModelViewer.prototype.loadStl = function(model) {
|
||||
var self = this;
|
||||
|
||||
var loader = new THREE.STLLoader();
|
||||
|
||||
loader.load(model, function (geometry) {
|
||||
self.addModel(geometry);
|
||||
});
|
||||
};
|
||||
|
||||
ModelViewer.prototype.centerCamera = function(mesh) {
|
||||
|
||||
var boxHelper = new THREE.BoxHelper( mesh );
|
||||
|
||||
var sceneCenter = this.objectCenter(mesh);
|
||||
|
||||
var geometry = mesh.geometry;
|
||||
|
||||
var distanceX = (geometry.boundingBox.max.x - geometry.boundingBox.min.x) / 2 / Math.tan(this.camera.fov * this.camera.aspect * Math.PI / 360);
|
||||
var distanceY = (geometry.boundingBox.max.y - geometry.boundingBox.min.y) / 2 / Math.tan(this.camera.fov * this.camera.aspect * Math.PI / 360);
|
||||
var distanceZ = (geometry.boundingBox.max.z - geometry.boundingBox.min.z) / 2 / Math.tan(this.camera.fov * Math.PI / 360);
|
||||
|
||||
var maxDistance = Math.max(Math.max(distanceX, distanceY), distanceZ);
|
||||
maxDistance *= 2.6 * this.scale;
|
||||
|
||||
var cameraPosition = this.camera.position.normalize().multiplyScalar(maxDistance);
|
||||
|
||||
this.controls.maxDistance = 3 * maxDistance;
|
||||
|
||||
this.controls.position0 = cameraPosition;
|
||||
this.controls.target0 = sceneCenter;
|
||||
this.controls.reset();
|
||||
};
|
||||
|
||||
ModelViewer.prototype.objectCenter = function (mesh) {
|
||||
var middle = new THREE.Vector3();
|
||||
var geometry = mesh.geometry;
|
||||
|
||||
geometry.center();
|
||||
geometry.computeBoundingBox();
|
||||
|
||||
middle.x = (geometry.boundingBox.max.x + geometry.boundingBox.min.x) / 2;
|
||||
middle.y = (geometry.boundingBox.max.y + geometry.boundingBox.min.y) / 2;
|
||||
middle.z = (geometry.boundingBox.max.z + geometry.boundingBox.min.z) / 2;
|
||||
|
||||
mesh.localToWorld(middle);
|
||||
return middle;
|
||||
};
|
||||
|
||||
ModelViewer.prototype.render = function() {
|
||||
this.renderer.render(this.scene, this.camera);
|
||||
};
|
Loading…
x
Reference in New Issue
Block a user