初识threejs,实现了简单的threejs和对象拾取。这里简单记录。
obj mtl 模型加载
这部分只实现了简单的模型加载,隐去html部分,最后贴完整源码
// 拾取变量
var objects = [];
var renderer, scene, camera;
var controls, group;
var stateView;
//
// 控制面板显示
control = new function (){
this.rotationSpeed = 0.005;
this.scale = 1;
this.rotationSpeed2 = 0.05;
this.sptSelectObj = false;
}
addControls(control);
// 性能显示
stateView = createStats();
// 通过原生的方式添加对象
//第一步创建场景元素
var scene=new THREE.Scene();
// ground
var mesh = new THREE.Mesh( new THREE.PlaneBufferGeometry( 2000, 2000 ), new THREE.MeshPhongMaterial( { color: 0x999999, depthWrite: false } ) );
mesh.rotation.x = - Math.PI / 2;
scene.add( mesh );
var grid = new THREE.GridHelper( 200, 40, 0x000000, 0x000000 );
grid.material.opacity = 0.2;
grid.material.transparent = true;
scene.add( grid );
// objects.push(mesh);
group = new THREE.Group();
scene.add(group);
obj = null;
var mtlLoader = new THREE.MTLLoader();//mtl材质加载器
mtlLoader.load( 'demo.mtl', function(materialss){
var objLoader = new THREE.OBJLoader();//obj模型加载器
objLoader.setMaterials( materialss );//mtl材质赋值给obj模型
objLoader.load( 'demo.obj',function(object3D){
obj = object3D;
// object3D.scale.set(100,100,100);//放大object3D对象
scene.add( object3D );//object3D对象插入场景对象
group.add( object3D );
} );//加载.obj文件,执行obj函数
});//加载.mtl文件,执行mtl函数
/
// 添加光源2
// lights
var light = new THREE.HemisphereLight( 0xffffff, 0x444444 );
light.position.set( 0, 20, 0 );
scene.add( light );
light = new THREE.DirectionalLight( 0xffffff );
light.position.set( 0, 20, 10 );
scene.add( light );
/
//添加相机 透视相机
var camera=new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 1, 1000);
camera.position.set(15, 15, 15);//相机的位置
camera.lookAt(scene.position);//相机朝向的位置
//添加渲染器
var renderer=new THREE.WebGLRenderer();
renderer.setPixelRatio( window.devicePixelRatio );
renderer.setSize(window.innerWidth, window.innerHeight);
//将渲染器加到文档中
document.body.appendChild(renderer.domElement);
function render() {
renderer.render(scene,camera);
}
render();//刚加载页面的时候就渲染一次 要不刚进入页面背景会是黑色的
//将相机加入到相机控制
var controls=new THREE.OrbitControls(camera, renderer.domElement);//不传参数默认是整个文档
//添加事件监听
// controls.addEventListener("change",renderer); //当事件改变 触发render方法 渲染界面
var animate = function () {
requestAnimationFrame( animate );
renderer.render( scene, camera );
stateView.update();
};
animate();
简单对象拾取(部分类型对象无法拾取)
对象拾取的思路是,摄像机到鼠标连线与模型求交,有交集的对象就是需要拾取的对象。来贴一下关键实现
// events
// checkbox.addEventListener( 'click', toggleOctree, false );
renderer.domElement.addEventListener( 'mousemove', onDocumentMouseMove, false );
window.addEventListener( 'resize', onWindowResize, false );
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize( window.innerWidth, window.innerHeight );
}
var selectedObject = null;
function onDocumentMouseMove( event ) {
event.preventDefault();
if ( selectedObject ) {
selectedObject.material.color.set( '#69f' );
selectedObject = null;
}
var intersects = getIntersects( event.layerX, event.layerY );
if ( intersects.length > 0 &&selectedObject!=intersects[0].object) {
var res = intersects.filter( function ( res ) {
return res && res.object;
} )[ 0 ];
if ( res && res.object ) {
selectedObject = res.object;
selectedObject.material.color.set( '#f00' );
}
}
}
var raycaster = new THREE.Raycaster();
var mouseVector = new THREE.Vector3();
function getIntersects( x, y ) {
x = ( x / window.innerWidth ) * 2 - 1;
y = - ( y / window.innerHeight ) * 2 + 1;
mouseVector.set( x, y, 0.5 );
raycaster.setFromCamera( mouseVector, camera );
return raycaster.intersectObject( group, true );
}
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize( window.innerWidth, window.innerHeight );
}
function addControls(controlObject){
var gui = new dat.GUI();
gui.add(controlObject,'rotationSpeed',-0.1,0.1);
gui.add(controlObject, 'scale', 0.01, 2);
gui.add(controlObject, 'rotationSpeed2', -0.1, 0.1);
}
function createStats() {
var stats = new Stats();
stats.setMode(0);
stats.domElement.style.position = 'absolute';
stats.domElement.style.left = '0px';
stats.domElement.style.top = '5px';
return stats;
}
引用的链接是http://www.cnblogs.com/pursues/p/5226807.html
真正实现拾取参考https://www.cnblogs.com/xuejianxiyang/p/9732632.html
https://blog.csdn.net/ithanmang/article/details/80897888
threejs 控制面板和性能检测集成https://www.cnblogs.com/hsprout/p/7865593.html
一个完整项目,源码有问题,但是项目开发思路可以借鉴http://www.cnblogs.com/pursues/p/5226807.html
本项目集成了一个html的魔板,用来改造界面,参考http://demo.cssmoban.com/cssthemes5/tpmo_518_sentra/index.html
下一步希望对模型内部对象,以及外部对象导入现在模型的实现。