Для этого проекта я пытаюсь создать сцену AR, где разные маркеры будут отображать разные модели.
Я могу загрузить и добавить модель .DAE с помощью загрузчика Collada и, как и ожидалось, когдапользователь заходит на веб-сайт, браузер запрашивает у пользователя разрешение на использование камеры.
Это достигается с помощью, как я уже говорил, ColladaLoader, добавляя модель в переменную с именем model1, масштабируя ее изатем вызывая функцию init.
Эта функция init создает средство визуализации, создает сцену, добавляет камеру и т. д., обрабатывает изменение размера браузера и добавляет маркеры модели.
Поскольку добавление одной модели сработало, яМысль добавить больше, я мог бы просто скопировать и вставить этот colladaloader и указать его на другую модель и установить новый маркер для него.К счастью, это работает, однако, когда я захожу на мобильный сайт, он невероятно медленный и спрашивает моего разрешения на использование камеры 7/8 раз (столько раз, сколько я загружал модели).Я думаю, это связано с тем, что после загрузки каждой модели все они вызывают функцию init.Таким образом, он создает и добавляет столько сцен, камер, визуализаций и т. Д., Сколько есть моделей.
Осматривая страницу, вы видите, что для каждой модели есть новый элемент canvas, когда должна быть только одна.
<script type="text/javascript">
var model1, axe, tree, sword, planks, minerals;
var loader = new THREE.ColladaLoader();
loader.load('greathallnow.DAE', function(collada) {
model1 = collada.scene;
model1.scale.x = model1.scale.y = model1.scale.z = 0.5;
init();
});
var loader = new THREE.ColladaLoader();
loader.load('axeyes.dae', function(collada) {
axe = collada.scene;
axe.scale.x = axe.scale.y = axe.scale.z = 0.3;
init();
});
var loader = new THREE.ColladaLoader();
loader.load('tree.dae', function(collada) {
tree = collada.scene;
tree.scale.x = tree.scale.y = tree.scale.z = 0.01;
init();
});
var loader = new THREE.ColladaLoader();
loader.load('swordplz.dae', function(collada) {
sword = collada.scene;
sword.scale.x = sword.scale.y = sword.scale.z = 0.3;
init();
});
var loader = new THREE.ColladaLoader();
loader.load('planks.dae', function(collada) {
planks = collada.scene;
planks.scale.x = planks.scale.y = planks.scale.z = 0.05;
init();
});
var loader = new THREE.ColladaLoader();
loader.load('stoneblockplural.dae', function(collada) {
minerals = collada.scene;
minerals.scale.x = minerals.scale.y = minerals.scale.z = 0.25;
init();
});
function init() {
// init renderer
var renderer = new THREE.WebGLRenderer({
antialias: true,
alpha: true
});
renderer.setClearColor(new THREE.Color('lightgrey'), 0)
renderer.setSize(640, 480);
renderer.domElement.style.position = 'absolute'
renderer.domElement.style.top = '0px'
renderer.domElement.style.left = '0px'
document.body.appendChild(renderer.domElement);
// array of functions for the rendering loop
var onRenderFcts = [];
// init scene and camera
var scene = new THREE.Scene();
// Create a camera
var camera = new THREE.Camera();
scene.add(camera);
var light = new THREE.HemisphereLight(0xffffbb, 0x080820, 1);
scene.add(light);
var arToolkitSource = new THREEx.ArToolkitSource({
sourceType: 'webcam'
});
arToolkitSource.init(function onReady() {
onResize()
});
// handle resize
window.addEventListener('resize', function() {
onResize()
});
function onResize() {
arToolkitSource.onResize()
arToolkitSource.copySizeTo(renderer.domElement)
if (arToolkitContext.arController !== null) {
arToolkitSource.copySizeTo(arToolkitContext.arController.canvas)
}
}
// create atToolkitContext
var arToolkitContext = new THREEx.ArToolkitContext({
cameraParametersUrl: THREEx.ArToolkitContext.baseURL + 'data/camera_para.dat',
detectionMode: 'mono',
})
// initialize it
arToolkitContext.init(function onCompleted() {
// copy projection matrix to camera
camera.projectionMatrix.copy(arToolkitContext.getProjectionMatrix());
})
// update artoolkit on every frame
onRenderFcts.push(function() {
if (arToolkitSource.ready === false) return
arToolkitContext.update(arToolkitSource.domElement)
})
var markerRoot = new THREE.Group;
scene.add(markerRoot);
var artoolkitMarker = new THREEx.ArMarkerControls(arToolkitContext, markerRoot, {
type: 'pattern',
patternUrl: THREEx.ArToolkitContext.baseURL + 'data/ghall-marker.patt',
});
var markerRoot2 = new THREE.Group;
scene.add(markerRoot2);
var artoolkitMarker = new THREEx.ArMarkerControls(arToolkitContext, markerRoot2, {
type: 'pattern',
patternUrl: THREEx.ArToolkitContext.baseURL + 'data/axe.patt',
});
var markerRoot3 = new THREE.Group;
scene.add(markerRoot3);
var artoolkitMarker = new THREEx.ArMarkerControls(arToolkitContext, markerRoot3, {
type: 'pattern',
patternUrl: THREEx.ArToolkitContext.baseURL + 'data/tree.patt', });
var markerRoot4 = new THREE.Group;
scene.add(markerRoot4);
var artoolkitMarker = new THREEx.ArMarkerControls(arToolkitContext, markerRoot4, {
type: 'pattern',
patternUrl: THREEx.ArToolkitContext.baseURL + 'data/sword.patt', });
var markerRoot5 = new THREE.Group;
scene.add(markerRoot5);
var artoolkitMarker = new THREEx.ArMarkerControls(arToolkitContext, markerRoot5, {
type: 'pattern',
patternUrl: THREEx.ArToolkitContext.baseURL + 'data/planks.patt', });
var markerRoot6 = new THREE.Group;
scene.add(markerRoot6);
var artoolkitMarker = new THREEx.ArMarkerControls(arToolkitContext, markerRoot6, {
type: 'pattern',
patternUrl: THREEx.ArToolkitContext.baseURL + 'data/minerals.patt', });
markerRoot.add(model1);
markerRoot2.add(axe);
markerRoot3.add(tree);
markerRoot4.add(sword);
markerRoot5.add(planks);
markerRoot6.add(minerals);
// render the scene
onRenderFcts.push(function() {
renderer.render(scene, camera);
})
// run the rendering loop
var lastTimeMsec = null
requestAnimationFrame(function animate(nowMsec) {
// keep looping
requestAnimationFrame(animate);
// measure time
lastTimeMsec = lastTimeMsec || nowMsec - 1000 / 60;
var deltaMsec = Math.min(200, nowMsec - lastTimeMsec);
lastTimeMsec = nowMsec;
TWEEN.update();
// call each update function
onRenderFcts.forEach(function(onRenderFct) {
onRenderFct(deltaMsec / 1000, nowMsec / 1000);
})
});
}
</script>
Я не думаю, что каждая модель должна вызывать функцию init, вместо этого я думаю, что все они должны быть загружены, и тогда есть только один init (), который добавляет их всех в сцену и отображает их всех,Мы надеемся, что это также улучшит производительность.Я просто не знаю, как это сделать?
Вы можете увидеть проблему, с которой я столкнулся, если вы посетите https://arevisit.madamot.com
Или вы можете увидеть, что происходит в этом видео на YouTubehttps://youtu.be/DjJdsBtfgvM
Большое спасибо, Адам