我一直在开发一个带有three.js的3d模型查看器,但我遇到了这个问题,我似乎找不到任何解决方案。
我希望在旋转时让2d叠加跟踪球体。 我设法对覆盖球体的覆盖进行编码,引用http://zachberry.com/blog/tracking-3d-objects-in-2d-with-three-js。
但是我希望隐藏跟踪覆盖图,同时球体被粗鲁的人屏蔽。
所以我试图计算相机和球体之间的交叉,以确定是否可以从相机中看到。
但是rayCaster.intersectObjects总是返回0。
这是我的代码。 我怎样才能阻止球体是否可见?
$(function() {
// Some defaults/hardcoded values:
var DEFAULT_VIEW_ANGLE = 45;
var DEFAULT_CAMERA_X = 0;
var DEFAULT_CAMERA_Y = 0;
var DEFAULT_CAMERA_Z = 200;
var PERSPECTIVE_NEAR = 0.1;
var PERSPECTIVE_FAR = 10000;
var WIDTH = $('#viewport').width();
var HEIGHT = $('#viewport').height();
// state
var rotate = true;
// three.js objects:
var renderer;
var scene;
var camera;
var projector;
var container;
var cube;
var sphere;
var pointLight;
var rayCaster;
// elements
var $trackingOverlay = $('#tracking-overlay');
// create three.js elements
projector = new THREE.Projector();
renderer = new THREE.WebGLRenderer();
rayCaster = new THREE.Raycaster();
scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera(DEFAULT_VIEW_ANGLE, WIDTH / HEIGHT, PERSPECTIVE_NEAR, PERSPECTIVE_FAR);
camera.position.set(DEFAULT_CAMERA_X, DEFAULT_CAMERA_Y, DEFAULT_CAMERA_Z);
pointLight = new THREE.PointLight(0xFFFFFF);
pointLight.position.set(10, 50, 150);
container = new THREE.Object3D();
cube = new THREE.Mesh(
new THREE.BoxGeometry(50, 50, 50),
new THREE.MeshLambertMaterial({wireframe: false, color: 0x00CC00})
);
cube.position.set(0, 0, 0);
sphere = new THREE.Mesh(
new THREE.SphereGeometry(4, 32, 32),
new THREE.MeshLambertMaterial({wireframe:false, color: 0xCCCC00})
);
sphere.position.set(0, 64, 0);
container.add(cube);
container.add(sphere);
scene.add(container);
scene.add(pointLight);
scene.add(camera);
// setup viewport
viewport = document.getElementById('viewport');
renderer.setSize(WIDTH, HEIGHT);
viewport.appendChild(renderer.domElement);
// start the animation loop
requestAnimationFrame(update);
function update()
{
if(rotate)
{
// hardcoded rotation for this demo:
container.rotation.z += 0.01;
container.rotation.x += 0.001;
container.rotation.y += 0.025;
}
renderer.render(scene, camera);
positionTrackingOverlay();
requestAnimationFrame(update);
}
function positionTrackingOverlay()
{
var visibleWidth, visibleHeight, p, v, percX, percY, left, top;
// this will give us position relative to the world
//p = sphere.matrixWorld.getPosition().clone();
p =new THREE.Vector3().setFromMatrixPosition(sphere.matrixWorld);
// projectVector will translate position to 2d
v = p.project(camera);
// translate our vector so that percX=0 represents
// the left edge, percX=1 is the right edge,
// percY=0 is the top edge, and percY=1 is the bottom edge.
percX = (v.x + 1) / 2;
percY = (-v.y + 1) / 2;
// scale these values to our viewport size
left = percX * WIDTH;
top = percY * HEIGHT;
// position the overlay so that it's center is on top of
// the sphere we're tracking
$trackingOverlay
.css('left', (left - $trackingOverlay.width() / 2) + 'px')
.css('top', (top - $trackingOverlay.height() / 2) + 'px');
if(isSphereVisible()){
$trackingOverlay.show();
}else{
$trackingOverlay.hide();
}
}
function isSphereVisible(){
rayCaster.setFromCamera(sphere,camera);
var intersects = rayCaster.intersectObjects(cube.children);
console.log(intersects.length);
return intersects.length>0?false:true;
}
});