Babylon.js将一个垂直于所点击表面的平面放置

时间:2014-11-13 11:18:52

标签: javascript 3d babylonjs

刚刚完成了关于如何检测click碰撞的babylon.js教程。 我的场景设置类似于this,只有我有更多的物体和移动的相机。

此脚本将平面移动到发生单击的位置。但它不会旋转平面,使其与您单击的曲面共面。

我很好奇如何将平面定位在垂直于被点击的表面上。

这是我的场景设置:

var canvas = document.getElementById("renderCanvas");
var engine = new BABYLON.Engine(canvas, true);

var createScene = function () {
    var scene = new BABYLON.Scene(engine);      
    scene.clearColor = new BABYLON.Color3(0.5, 0.5, 0.5);

    var camera = new BABYLON.FreeCamera("FreeCamera", new BABYLON.Vector3(0, 1, -15), scene);
    scene.activeCamera = camera;
    scene.activeCamera.attachControl(canvas);
    camera.inertia = 0;
    camera.speed = 50;

    var light3 = new BABYLON.HemisphericLight("Hemi0", new BABYLON.Vector3(0, 1, 0), scene);
    light3.diffuse = new BABYLON.Color3(1, 1, 1);
    light3.specular = new BABYLON.Color3(1, 1, 1);
    light3.groundColor = new BABYLON.Color3(0, 0, 0);
    light3.intensity = .7;

        var sphere = BABYLON.Mesh.CreateSphere("sphere1", 16, 2, scene);        
        var box = BABYLON.Mesh.CreateBox("box", 6.0, scene);        
        var ground = BABYLON.Mesh.CreateGround("ground1", 32, 32, 2, scene);
      // a plane that is moved when click hits a surface
        var decal = BABYLON.Mesh.CreatePlane("plane", 3.0, scene);

        box.position = new BABYLON.Vector3(0, 0.1, 0);
        box.scaling.x = (1); box.scaling.y = (0.05); box.scaling.z = (1);
        box.rotation.z = (Math.PI/4);
        sphere.position.y = 8;
        ground.position.y = -2; 

        var matGnd = new BABYLON.StandardMaterial("gnd", scene);
        ground.material = matGnd;
        matGnd.diffuseColor = new BABYLON.Color3(1.0, 0.2, 0.7);

        var matDecal = new BABYLON.StandardMaterial("decalM", scene);
        decal.material = matDecal;
        matDecal.diffuseColor = new BABYLON.Color3(1.0, 0, 0);

scene.registerBeforeRender(function () {
window.addEventListener("click", function (evt) {
   var pickResult = scene.pick(evt.clientX, evt.clientY);    
            if (pickResult.hit) {
                        decal.position.x = pickResult.pickedPoint.x;
                        decal.position.y = pickResult.pickedPoint.y;
            }
        });

    });

        return scene;
  };             

1 个答案:

答案 0 :(得分:3)

我知道这是一个古老的问题,但它可能会为寻找类似事物的其他人派上用场。

  1. 检查pickResult是否有命中(你已经这样做了)
  2. 获取您点击的点(或面)的法线 -

    var pickNormal = pickResult.getNormal();
    
  3. 使用Cross和Dot产品计算平面法线和pickResult法线之间的旋转(假设平面正常):

    var rotationAxis = BABYLON.Vector3.Cross(pickNormal, planeNormal).normalize();
    var angle = Math.acos(BABYLON.Vector3.Dot(pickNormal, planeNormal)); 
    
  4. 旋转飞机:

    decal.rotate(rotationAxis,angle);
    
  5. (可选)为平面设置新位置

    decal.position = pickResult.pickedPoint;