MindAR JS: MINDAR.IMAGE.MindARThree is not a constructor - javascript

I am learning Web AR development using MindAR, https://hiukim.github.io/mind-ar-js-doc/#:~:text=MindAR%20is%20an%20opensource%20web,are%20written%20for%20AFRAME%20integration. I am following a tutorial on Udemy, https://www.udemy.com/course/introduction-to-web-ar-development/learn/lecture/29791078#overview. But it is not working unfortunately for me but for the instructor.
This is my index.html page.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>AR Research</title>
<script src="https://cdn.jsdelivr.net/npm/mind-ar#1.1.5/dist/mindar-image.prod.js"></script>
<script src="https://aframe.io/releases/1.2.0/aframe.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/mind-ar#1.1.5/dist/mindar-image-aframe.prod.js"></script>
<script src="./main.js" type="module">
</script>
<style>
html, body {
position: relative;
margin: 0;
width: 100%;
height: 100%;
overflow: hidden;
}
</style>
</head>
<body>
</body>
</html>
As you can see there is not much in the code. I basically embedded the required Mind AR libraries through CDN and add the css styling a little bit and reference my main.js file.
This is my main.js file.
document.addEventListener(`DOMContentLoaded`, () => {
const start = async () => {
// create the AR world and specify the marker
const mindarThree = new window.MINDAR.IMAGE.MindARThree({
container: document.body,
imageTargetSec: './groot.mind'
})
const { renderer, scene, camera } = mindarThree;
const geometry = new THREE.PlaneGeometry(1, 1);
const material = new THREE.MeshBasicMaterial({ color: 0x0000ff, transparent: true, opacity: 0.5 });
const plane = new THREE.Mesh(geometry, material);
const anchor = mindarThree.addAnchor(0);
anchor.group.add(plane);
await mindarThree.start();
renderer.setAnimationLoop(() => {
renderer.render(scene, camera);
})
}
start();
})
When I run the code on the browser, I am getting the following error.
main.js:4 Uncaught (in promise) TypeError: MINDAR.IMAGE.MindARThree is not a constructor
at start (main.js:4:29)
at HTMLDocument.<anonymous> (main.js:24:5)
What is wrong with my code and how can I fix it?

I had the same problem. The solution is that a different MindAR package needs to be imported, the one that combines MindAR and Three.js:
Use this one:
https://cdn.jsdelivr.net/npm/mind-ar#1.1.5/dist/mindar-image-three.prod.js
Not this one:
https://cdn.jsdelivr.net/npm/mind-ar#1.1.5/dist/mindar-image.prod.js

Related

Uncaught TypeError:Class constructor Scene cannot be invoked without 'new' line:391 of:file:///storage/emulated/0/threejs/libs/physi.js

I have been using Physijs with the older version of three.js and it works perfectly
But when I downloaded the latest version of threejs it doesn't work even to just put a plane mesh on the scene
It brings out this error
Uncaught TypeError: Class constructor Scene cannot be invoked without 'new' line:391 of:file:///storage /emulated/0/threejs /learning-threejs/libs/physi .js
I don't understand why exactly
Here's my code
<html>
<head>
<title>Example 01.01 - Basic skeleton</title>
<script type="text/javascript" src="../libs/three.min.js"></script>
<script type="text/javascript" src="../libs/dat.gui.js"></script>
<script type="text/javascript" src="../libs/TrackballControls.js"></script>
<script type="text/javascript" src="../libs/physi.js"></script>
<style>
body {
/* set margin to 0 and overflow to hidden, to
use the complete page */
margin: 0;
overflow: hidden;
}
</style>
</head>
<body>
<!-- Div which will hold the Output -->
<div id="WebGL-output">
</div>
<!-- Javascript code that runs our Three.js examples -->
<script type="text/javascript">
// once everything is loaded, we run our Three.js stuff.
function init() {
Physijs.scripts.worker = '../libs/physijs_worker.js';
Physijs.scripts.ammo = '../libs/ammo.js';
//renderer
var renderer=new THREE.WebGLRenderer({antialias:true})
renderer.setSize(innerWidth,innerHeight)
renderer.setPixelRatio=devicePixelRatio
renderer.shadowMap.enabled=true
renderer.setClearColor(new THREE.Color(0xff00ff))
//physijs scene
var scene=new Physijs.Scene
scene.setGravity(new THREE.Vector3(0,-300,-50))
//ground
var groundgeo=new THREE.PlaneGeometry(50,50)
var groundmat=new Physijs.createMaterial(new THREE.MeshBasicMaterial({color:0xd2b48c ,side:THREE.DoubleSide}))
var ground=new Physijs.PlaneMesh(groundgeo,groundmat,0)
ground.rotation.x=-0.5*Math.PI
ground.position.set(-20.0,0,0.0)
ground.receiveShadow=true
scene.add(ground)
var camera=new THREE.PerspectiveCamera(40,innerWidth/innerHeight,0.1,10000)
camera.position.set(70,65,0)
camera.lookAt(ground.position)
scene.add(camera)
var trackballControls = new THREE.TrackballControls(camera);
trackballControls.rotateSpeed = 1.0;
trackballControls.zoomSpeed = 1.0;
trackballControls.panSpeed = 1.0;
trackballControls.staticMoving = true;
document.getElementById("WebGL-output").appendChild(renderer.domElement)
render()
var step=0
function render(){
scene.simulate(undefined,2)
trackballControls.update()
requestAnimationFrame(render)
renderer.render(scene,camera)
}}
window.onload = init()
</script>
</body>
Thanks in advance
The new version of three js doesn't support physi.js but it support Cannon.js
So cannon.js(or other recent physics library) should be used instead of physi.js

Three.js - Uncaught ReferenceError: OBJLoader is not defined

I'm following several tutorials on Three.js, yet I keep getting a Uncaught ReferenceError: OBJLoader is not defined error when trying to implement my own .obj file. Tried different methods, nothing is helping. Been stuck on this problem for days.
I'm running on localhost using http-server.
Oddly enough, when I switch the new OBJLoader(); to new THREE.ObjectLoader(); it seems to work as it tries to load the file, albeit the file is not a .json file, it is an .obj so it throws an error.
HTML
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>three.js crash course</title>
<link rel="stylesheet" href="css/styles.css">
</head>
<body>
<script type="module" src="js/jQuery.js"></script>
<script type="module" src="js/three.min.js"></script>
<script type="module" src="js/OrbitControls.js"></script>
<script type="module" src="loaders/GLTFLoader.js"></script>
<script type="module" src="loaders/OBJLoader.js"></script>
<script type="module" src="js/index.js"></script>
</body>
</html>
JS
window.onload = function() {
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(75, window.innerWidth/window.innerHeight, 0.1, 1000);
var renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
$(window).resize(function(){
var width = window.innerWidth;
var height = window.innerHeight;
renderer.setSize(width, height);
camera.aspect = width/height;
camera.updateProjectionMatrix();
});
var controls = new THREE.OrbitControls(camera, renderer.domElement);
const loader = new OBJLoader();
loader.load (
// resource URL
'./models/boat_large.obj',
// called when resource is loaded
function ( object ) {
scene.add( object );
},
// called when loading is in progresses
function ( xhr ) {
console.log( ( xhr.loaded / xhr.total * 100 ) + '% loaded' );
},
// called when loading has errors
function ( error ) {
console.log( 'An error happened' );
}
);
camera.position.z = 3;
var ambientLight = new THREE.AmbientLight(0xFFFFFF, 0.8);
// game logic
var update = () => {
};
// draw scene
var render = () => {
renderer.render(scene, camera);
};
// run game loop (update, render, repeat)
var GameLoop = () => {
requestAnimationFrame(GameLoop);
update();
render();
}
GameLoop();
}
You need to use new THREE.OBJLoader() when you reference the javascript files like that.
The reason it works in the ThreeJS example is, because it is imported via
import { OBJLoader } from './jsm/loaders/OBJLoader.js';
.
Alternatively you could include the file like it is shown in the example
.
In your case it would obviously be something like
import { OBJLoader } from '../loaders/OBJLoader.js';
assuming the JS posted above is from index.js.
it worked for me adding the following import:
import {OBJLoader} from 'three/examples/jsm/loaders/OBJLoader';

How to use p5.js sound in instance mode

I'm trying to make a website with multiple p5 canvases on the same page, so after a lot of research, I came to the conclusion that the most adequate way to do that is by using instance mode on p5.
I spent the whole day trying to understand the instance mode, i even found a converter online that converts it for me, but I'm trying to do it all by my self using it just to check errors. The problem is that i can't find a way to use sound in my sketch using instance mode. the code i have is a lot more complex, but even trying just the basic it still does not work.
var s = function(p) {
let song;
p.preload = function() {
p.song = load('thunder.mp3')
}
p.setup = function() {
p.createCanvas(720, 200);
p.background(255, 0, 0);
p.song.loop();
};
};
var myp5 = new p5(s, 'c1');
html, body {
margin: 0;
padding: 0;
}
canvas {
display: block;
}
<html>
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.1.9/p5.js"></script>
<script language="javascript" type="text/javascript" src="sketch.js"></script>
<style> body {padding: 0;
margin: 0;
}
<meta charset="UTF-8">
</style>
</head>
<body>
<div id="c1"></div> <br>
<div id="c2"></div>
</body>
</html>
you can test it here: https://editor.p5js.org/jgsantos.dsn/sketches/rUWb6Nurt
This code works great in the global mode:
let song;
function preload() {
song = loadSound('thunder.mp3');
}
function setup() {
createCanvas(720, 200);
background(255,0,0);
song.loop();
}
html, body {
margin: 0;
padding: 0;
}
canvas {
display: block;
}
<!DOCTYPE html>
<html lang="en">
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.1.9/p5.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.1.9/addons/p5.sound.min.js"></script>
<link rel="stylesheet" type="text/css" href="style.css">
<meta charset="utf-8" />
</head>
<body>
<script src="sketch.js"></script>
</body>
</html>
You can test it here https://editor.p5js.org/jgsantos.dsn/sketches/_lQcDqOsp
It shows this error: "Uncaught ReferenceError: load is not defined (: line 9)"
What am I'm doing wrong?
Thanks in advance!
Please try to post the exact code you're running. Your question contains different code than the link you posted in the comments.
But taking a step back, here's how I would think about instance mode and libraries:
Instance mode means that the variables and functions that belong to a sketch are now referenced via a variable, in your case the p variable.
But variables and functions that belong to a library are still referenced directly, i.e. in "global mode".
In other words, you don't want to reference the load() (or is it loadSound()?) function using instance mode. You should still reference that function directly, since it's coming from a library instead of from a specific sketch.

Defining Position in Phaser

I'm making a very basic game in Javascript using the Phaser Directory. I have made games with Phaser many times before but this time I have come across an issue that is new to me and I've never had before. I've looked it up online and no one seems to have had this problem. In phaser it is telling me my "x" is not defined when I refer to x as a position. How would I go about defining x as a position or what error am I facing? I and currently using VS Code on mac with a Chrome browser and newest version of Phaser.
Thanks for the Help,
Murdoc
var game = new Phaser.Game(640, 360, Phaser.Auto);
var car1;
var GameState = {
preload: function(){
game.load.image("thecar1", "../assets/car_1.png");
//game.load.image("thecar2", "../assets/car_2.png");
//game.load.image("backgroundImg", "../assets/thebackground.png");
},
create: function(){
var car1 = game.add.sprite(200, 270, "thecar1");
//var car2 = game.add.sprite(200, 270, "thecar2");
/*game.input.keyboard.addKey(Phaser.Keyboard.W)
.onDown.add(car1Up);*/
game.input.keyboard.addKey(Phaser.Keyboard.A)
.onDown.add(car1Left);
/*game.input.keyboard.addKey(Phaser.Keyboard.S)
.onDown.add(car1Down);
game.input.keyboard.addKey(Phaser.Keyboard.D)
.onDown.add(car1Right);*/
},
update: function(){
}
};
function car1Left() {
car1.x = car1.x + 10;
}
game.state.add('GameState', GameState);
game.state.start('GameState');
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Pixel Soccer</title>
<script src="phaser.js"></script>
<script src="main.js"></script>
<style>
body {
background: white;
margin: 0;
padding: 0;
}
body canvas {
margin-left: auto;
margin-right: auto;
}
</style>
</head>
<body>
</body>
</html>
You're declaring the same variable twice. You're dealing with what's called "variable shadowing". When you do var car1 = game.add.sprite(200, 270, "thecar1"); in the create() function, the scope changes to function-only and the variable with the sprite you assign to it is only available in the scope of that function. The error basically comes to tell you that var car1 that you declared outside of the function scope is undefined (which it is). Try doing just car1 = game.add.sprite(200, 270, "thecar1"); inside create() and it should be fine.

render result is pixelated (or: has lower resolution that it should)

I'm doing some prototyping, and I'm displaying some data in 3D using three.js (version 68). Desired result of whole animation would be a bunch of colored balls (that represent protons and neutrons that are colored according to some schema). Everything works good, but for reasons unknown to me rendered results are pixcelated.
Current version basically looks like that (this image is ~400px wide):
I have checked all obvious things like: passing incorrect resolution, browser scaling and so forth.
You can see this issue on this fiddle, and download the webpage here.
And also here are revelant parts of code:
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<script src="js/jquery.js"></script>
<script src="js/coffee-script.js"></script>
<script src="js/three.js"></script>
<script src="js/OrbitControls.js"></script>
<script src="js/animtest/load_event.js"></script>
<style>canvas { width: 100%; height: 100% }</style>
<title></title>
</head>
<body>
<div id="animation"
style="width: 1024px; height: 768px; ">
</div>
<script>
$(function(){
ctrl = new AnimController("#animation");
ctrl.set_up_scene();
ctrl.render();
ctrl.display_frame(4);
});
</script>
</body>
</html>
Here is the coffeescript code that loads the animation:
class AnimController
...
set_up_scene: () ->
#scene = new THREE.Scene()
el = $(#element_name)
#camera = new THREE.PerspectiveCamera(45
el.width()/el.height(),
1, 20000
)
#camera.position.set(100, 100, 0)
#scene.add new THREE.AmbientLight 0x111111
#renderer = new THREE.WebGLRenderer()
el.html(#renderer.domElement)
controls = new THREE.OrbitControls(#camera, #renderer.domElement );
controls.addEventListener 'change', () =>
console.log("Change")
#render()
render: () ->
requestAnimationFrame(() => #render)
console.log "Render"
if #update_scene
material = new THREE.MeshBasicMaterial() #"color": 0xffff00,
geometry = new THREE.SphereGeometry 5, 50, 50
console.log "Update"
#update_scene = false
#scene = new THREE.Scene()
for particle in #curr_event
p = particle['position']
sphere = new THREE.Mesh( geometry, material );
sphere.position.set(p[0], p[1], p[2])
#scene.add(sphere)
#renderer.render(#scene, #camera)
It seems that you have not requested antialiasing on the renderer you are using. I don't know coffeescript but in javascript you would do:
renderer = new THREE.WebGLRenderer({ antialias: true });
Antialiasing also was a factor (see #gaitat answer) but I also forgot to set resoluion the renderer:
renderer.setSize( 1024, 768 )

Categories

Resources