在查看Babylon-background时偶然发现的一段代码
这段代码介绍了拖动一张图片,放置到画布中,生成对应的三维模型
// 主要灵感来自: https://www.babylonjs-playground.com/#25LQ6Q
// 不知道这一行的重点是什么 -_-;
$('#file').remove();
// 通过jquery添加HTML图像对象
$('body').append('<img id="file" src="https://d33wubrfki0l68.cloudfront.net/76ba779f6c3b4c5b893b49e300793b6604ee141e/6f62c/img/resources/meshes/skull.png" width="100px" draggable="true" style="position:absolute; right:10px; top:150px; z-index: 10000;"/>');
var createScene = function () {
// 创建基础babylon场景对象
var scene = new BABYLON.Scene(engine);
// 在场景中添加相机
var camera = new BABYLON.ArcRotateCamera("Camera", 5 ,1, 10, BABYLON.Vector3.Zero(),scene);
// 设置相机的移动范围
camera.lowerRadiusLimit = 2;
camera.upperRadiusLimit = 25;
// 防止鼠标滚轮过快的移动
camera.wheelPrecision = 50;
// 把相机添加到画布
camera.attachControl(canvas, true);
// 创建灯光
var light = new BABYLON.HemisphericLight("light", new BABYLON.Vector3(0, 5, 0), scene);
// 设置曝光度
light.intensity = 0.7;
// 创建地面
var ground = BABYLON.MeshBuilder.CreateGround("ground", {width: 10, height: 10}, scene);
// 加载头骨模型,将包含所有加载网格列表的对象
var models = {};
var instCount = 0;
// assetsManager用于加载所有相关的模型和纹理
var assetsManager = new BABYLON.AssetsManager(scene);
// 在这里我们预加载头骨
var meshTask = assetsManager.addMeshTask("task1", "", "./scenes/", "skull.babylon");
meshTask.onSuccess = function (task) {
for (i = 0; i < task.loadedMeshes.length; i++) {
// 对象有点太大,所以缩小尺寸
task.loadedMeshes[i].scaling = new BABYLON.Vector3(0.01, 0.01, 0.01);
// 将对象设置在场景的中间
task.loadedMeshes[i].position = new BABYLON.Vector3(0,0.3,0);
// 这将在加载时隐藏网格
task.loadedMeshes[i].setEnabled(false);
// 将它们添加到我们的模型对象中,我们稍后将通过它们的名称调用它们
models[task.loadedMeshes[i].name] = task.loadedMeshes[i];
}
}
// 如果加载出错,我们将在控制台中进行提示
meshTask.onError = function (task, message, exception) {
console.log(message, exception);
}
assetsManager.load();
// 创建gizmoManager对象
var gizmoManager = new BABYLON.GizmoManager(scene);
gizmoManager.boundingBoxGizmoEnabled = true;
gizmoManager.boundingBoxDragBehavior = null;
gizmoManager.usePointerToAttachGizmos = true;
gizmoManager.clearGizmoOnEmptyPointerEvent = true;
/**
* 将自己的pointerDragBehavoir附加到给定网格
* pointerDragBehavoir只能容纳一个附加的网格(attachedNode属性),
* 因此,该函数将创建“唯一”pointerDragBehavoirs并将其添加到网格
*/
function attachOwnPointerDragBehavior(mesh){
// 在所需模式下创建pointerDragBehavior
var pointerDragBehavior = new BABYLON.PointerDragBehavior({dragPlaneNormal: new BABYLON.Vector3(0,1,0)});
// 如果需要手动处理拖动事件,请将move-attached设置为false
pointerDragBehavior.moveAttached = false;
// 在世界空间中使用拖动平面
pointerDragBehavior.useObjectOrienationForDragging = false;
// 收听拖动事件
pointerDragBehavior.onDragStartObservable.add((event)=>{})
pointerDragBehavior.onDragEndObservable.add((event)=>{})
pointerDragBehavior.onDragObservable.add((event)=>{
// 当Babylon获得更新时,也可以使用attachedNode
mesh.position.x += event.delta.x;
mesh.position.z += event.delta.z;
})
// 将自己的pointerDragBehavoir附加到给定网格
mesh.addBehavior(pointerDragBehavior);
}
var file = document.getElementById('file');
var newInstance = BABYLON.Mesh;
var startdrag = function(evt){
evt.dataTransfer.setData("text", evt.target.src);
// 当我们开始拖动时,将隐藏/删除“重影”图像
evt.dataTransfer.setDragImage(new Image(), 0, 0);
newInstance = models["test"].createInstance("skull_" + instCount);
var target = BABYLON.Vector3.Unproject(
new BABYLON.Vector3(scene.pointerX, scene.pointerY, 0),
canvas.width,
canvas.height,
new BABYLON.Matrix.Identity(),
camera.getViewMatrix(),
camera.getProjectionMatrix()
);
target.x = camera.position.x - target.x;
target.y = camera.position.y - target.y;
target.z = camera.position.z - target.z;
var p = getZeroPlaneVector(camera.position, target);
newInstance.position = p;
};
file.addEventListener('dragstart', startdrag, false);
// 拖动结束
var dragover = function(evt){
evt.preventDefault();
var target = BABYLON.Vector3.Unproject(
new BABYLON.Vector3(evt.offsetX, evt.offsetY, 0),
canvas.width,
canvas.height,
new BABYLON.Matrix.Identity(),
camera.getViewMatrix(),
camera.getProjectionMatrix()
);
target.x = camera.position.x - target.x;
target.y = camera.position.y - target.y;
target.z = camera.position.z - target.z;
var p = getZeroPlaneVector(camera.position, target);
newInstance.position = p;
}
canvas.addEventListener('dragover', dragover, false);
// DROP-事件
var drop = function (evt) {
evt.preventDefault();
attachOwnPointerDragBehavior(newInstance);
gizmoManager.attachToMesh(newInstance);
instCount++;
}
canvas.addEventListener('drop', drop, false);
return scene;
};
var getZeroPlaneVector = function (pos, rot) {
return getHorizontalPlaneVector(0, pos, rot);
};
var getHorizontalPlaneVector = function (y, pos, rot) {
if (!rot.y) {
return null; // no solution, as it will never hit the zero plane
}
return new BABYLON.Vector3(
pos.x - (pos.y - y) * rot.x / rot.y,
1,
pos.z - (pos.y - y) * rot.z / rot.y
);
};