Three.js object definition not defining - javascript

I am working my way through a set of tutorials and have come across an error I cant figure out...
I know it is probably me being blind due to my lazy upbringing with IDE's that have red underlines for syntax errors but I kinda need this done soon!
The error is
TypeError: Tetris.boundingBoxConfig is undefined
file:///C:/Users/Timmy/Documents/Emergent%20Tech/Tetris/js/tetris.js
Line 127
here i define Tetris.boundingBoxConfig
var boundingBoxConfig = {
width: 360,
height: 360,
depth: 1200,
splitX: 6,
splitY: 6,
splitZ: 20
};
Tetris.boundingBoxConfig = boundingBoxConfig;
and here is line 127
mesh.position.x = (x - Tetris.boundingBoxConfig.splitX/2)*Tetris.blockSize + Tetris.blockSize/2;
if you need more of the code let me know and I will edit. Any Help would be much appreciated! please only constructive criticism
EDIT Definition of Tetris Object
var Tetris = {};
There was a second suggested way of doing it like this:
window.Tetris = window.Tetris || {};
but i don't really get how that way works
EDIT 2
Not sure if this helps the clarify the issue
var boundingBox = new THREE.Mesh(
new THREE.CubeGeometry(
boundingBoxConfig.width, boundingBoxConfig.height, boundingBoxConfig.depth,
boundingBoxConfig.splitX, boundingBoxConfig.splitY, boundingBoxConfig.splitZ),
new THREE.MeshBasicMaterial( { color: 0xffaa00, wireframe: true } )
);
Tetris.scene.add(boundingBox);

Inside your Tetris function, try changing
Tetris.boundingBoxConfig = boundingBoxConfig;
To
this.boundingBoxConfig = { //your definition };
so that your property becomes public.

Turns out this was due to me using local files in Firefox. I knew that Chrome had security issues when loading the files from a local disk so went with Firefox believing there was not a similar problem due to other projects working. I was wrong.
Lesson: Never use local files always use a server.

Could you please include the code where you have defined the "Tetris" object? (ie var Tetris blah blah blah)

Related

javascript games ThreeJS and Box2D conflicts?

I've been trying to experiment with box2d and threejs.
So box2d has a series of js iterations, I've been successful at using them so far in projects as well as threejs in others, but I'm finding when including the latest instance of threejs and box2dweb, threejs seems to be mis-performing when just close to box2dweb but maybe I'm missing something really simple, like a better way to load them in together, or section them off from one another?
I've tried a few iterations of the box2d js code now and I always seemed to run into the same problem with later versions of threejs and box2d together! - currently version 91 threejs.
The problem I'm seeing is very weird.
I'm really hoping someone from either the box2d camp or threejs camp can help me out with this one, please?
Below is a very simple example where I don't initialize anything to do with box2d, but just by having the library included theres problems and you can test by removing that resource, then it behaves like it should.
The below demo uses threejs 91 and box2dweb. It is supposed to every couple of seconds create a box or a simple sphere each with a random colour. Very simple demo, you will see the mesh type never changes and the colour seems to propagate across all mesh instances. However if you remove the box2dweb resource from the left tab then it functions absolutely fine, very odd :/
jsfiddle link here
class Main {
constructor(){
this._container = null;
this._scene = null;
this._camera = null;
this._renderer = null;
console.log('| Main |');
this.init();
}
init(){
this.initScene();
this.addBox(0, 0, 0);
this.animate();
}
initScene() {
this._container = document.getElementById('viewport');
this._scene = new THREE.Scene();
this._camera = new THREE.PerspectiveCamera(75, 600 / 400, 0.1, 1000);
this._camera.position.z = 15;
this._camera.position.y = -100;
this._camera.lookAt(new THREE.Vector3());
this._renderer = new THREE.WebGLRenderer({antialias:true});
this._renderer.setPixelRatio( 1 );
this._renderer.setSize( 600, 400 );
this._renderer.setClearColor( 0x000000, 1 );
this._container.appendChild( this._renderer.domElement );
}
addBox(x,y,z) {
var boxGeom = new THREE.BoxGeometry(5,5,5);
var sphereGeom = new THREE.SphereGeometry(2, 5, 5);
var colour = parseInt(Math.random()*999999);
var boxMat = new THREE.MeshBasicMaterial({color:colour});
var rand = parseInt(Math.random()*2);
var mesh = null;
if(rand == 1) {
mesh = new THREE.Mesh(boxGeom, boxMat);
}
else {
mesh = new THREE.Mesh(sphereGeom, boxMat);
}
this._scene.add(mesh);
mesh.position.x = x;
mesh.position.y = y;
mesh.position.z = z;
}
animate() {
requestAnimationFrame( this.animate.bind(this) );
this._renderer.render( this._scene, this._camera );
}
}
var main = new Main();
window.onload = main.init;
//add either a box or a sphere with a random colour every now and again
setInterval(function() {
main.addBox(((Math.random()*100)-50), ((Math.random()*100)-50), ((Math.random()*100)-50));
}.bind(this), 4000);
so the way im including the library locally is just a simple...
<script src="js/vendor/box2dweb.js"></script>
So just by including the box2d library threejs starts to act weird, I have tested this across multiple computers too and multiple version of both box2d (mainly box2dweb) and threejs.
So with later versions of threejs it seems to have some comflicts with box2d.
I found from research that most of the box2d conversions to js are sort of marked as not safe for thread conflicts.
Im not sure if this could be the cause.
I also found examples where people have successfully used box2d with threejs but the threejs is always quite an old version, however you can see exactly the same problems occurring in my example, when I update them.
So below is a demo I found and I wish I could credit the author, but here is a copy of the fiddle using threejs 49
jsfiddle here
.....and then below just swapping the resource of threejs from 49 to 91
jsfiddle here
its quite an odd one and maybe the two libraries just don't play together anymore but would be great if someone can help or has a working example of them working together on latest threejs version.
I have tried a lot of different box2d versions but always found the same problem, could this be a problem with conflicting libraries or unsafe threads?
but also tried linking to the resource include in the fiddles provided.
Any help really appreciated!!

When does "Argument 2 of WebGLRenderingContext.uniform4fv could not [...]" appear using three.js?

I am trying to extend a JS game that uses Three.js as API. A problem that has occured recently is this error:
TypeError: Argument 2 of WebGLRenderingContext.uniform4fv could not be converted to any of: Float32Array, UnrestrictedFloatSequence.
The line in the code causing this is the basic render call of the game:
renderer.render(scene, camera);
I could now paste the messy code here but thats not why I am here. I hope somebody has ever experienced that too and can tell me what the problem is.
Note:
I. The original error is from within Three.js (The internal render stuff)
three.min.js:7:118
II.The first frame can be rendered without any problem, after that the error occurs
III. The scene is made of a few simple objects, but the source of the problem is this object:
this.geometry = new THREE.PlaneGeometry(0.8, 0.8);
this.texture = new THREE.TextureLoader().load("graphics/racers/" + racer + ".png", function () { return;});
this.texture.generateMipmaps = false;
this.texture.minFilter = THREE.NearestFilter;
this.texture.magFilter = THREE.NearestFilter;
this.texture.repeat.set(0.25, 1);
this.material = new THREE.MeshBasicMaterial({ map: this.texture, transparent: true });
this.mesh = new THREE.Mesh(this.geometry, this.material);
scene.add(this.mesh);
If you need anything else feel free to ask.
Thanks in advance!
EDIT:
I found out that the error only appears when the Mesh-Object (mentioned above) is seen by the camera!
It turns out I was a fool all along ^^
I used
texture.offset = 0.25;
instead of
texture.offset.x = 0.25;
Wow! Feels great losing time for such a mistake :D Anyway: Won't do it again. A lesson for life!
Asset loading is asynchronous and most probably your texture has not loaded by the time you are using it. Use the example at https://threejs.org/docs/index.html?q=TextureL#api/loaders/TextureLoader

Cesium - why is scene.pickPositionSupported false

I'm ultimately trying to draw a polygon on top of my house. I can do that.
The problem is that on zoom-out, zoom-in, and rotation (or camera move) the polygon doesn't stick to the top of my house. I received great help from this answer. So, now I'm trying to go through the sample code but there is a lot of Cesium methods and functionality that I need to learn.
The sample code I am trying to follow is located in the gold standard that appears to be baked into the existing camera controller here.
I call testMe with the mousePosition as Cartesian3 and the SceneMode is 3D, so pickGlobe is executed.
Here is my code:
var pickedPosition;
var scratchZoomPickRay = new Cesium.Ray();
var scratchPickCartesian = new Cesium.Cartesian3();
function testMe(mousePosition) {
if (Cesium.defined(scene.globe)) {
if(scene.mode !== Cesium.SceneMode.SCENE2D) {
pickedPosition = pickGlobe(viewer, mousePosition, scratchPickCartesian);
} else {
pickedPosition = camera.getPickRay(mousePosition, scratchZoomPickRay).origin;
}
}
}
var pickGlobeScratchRay = new Cesium.Ray();
var scratchDepthIntersection = new Cesium.Cartesian3();
var scratchRayIntersection = new Cesium.Cartesian3();
function pickGlobe(viewer, mousePosition, result) {
var globe = scene.globe;
var camera = scene.camera;
if (!Cesium.defined(globe)) {
return undefined;
}
var depthIntersection;
if (scene.pickPositionSupported) {
depthIntersection = scene.pickPosition(mousePosition, scratchDepthIntersection);
}
var ray = camera.getPickRay(mousePosition, pickGlobeScratchRay);
var rayIntersection = globe.pick(ray, scene, scratchRayIntersection);
var pickDistance;
if(Cesium.defined(depthIntersection)) {
pickDistance = Cesium.Cartesian3.distance(depthIntersection, camera.positionWC);
} else {
pickDistance = Number.POSITIVE_INFINITY;
}
var rayDistance;
if(Cesium.defined(rayIntersection)) {
rayDistance = Cesium.Cartesian3.distance(rayIntersection, camera.positionWC);
} else {
rayDistance = Number.POSITIVE_INFINITY;
}
var scratchCenterPosition = new Cesium.Cartesian3();
if (pickDistance < rayDistance) {
var cart = Cesium.Cartesian3.clone(depthIntersection, result);
return cart;
}
var cart = Cesium.Cartesian3.clone(rayIntersection, result);
return cart;
}
Here is my problem:
Here is the result:
Here are my questions to get this code working:
1. How do I get the scene.pickPositionSupported set to true? I'm using Chrome on Windows 10. I cannot find in the sample code anything about this and I haven't had much luck with the documentation or Google.
2. Why is rayIntersection not getting set? ray and scene have values and scratchRayIntersection in an empty Cartesian3.
I think if I can get those two statements working, I can probably get the rest of the pickGlobe method working.
WebGLGraphics Report:
I clicked on Get WebGL and the cube is spinning!
Picking positions requires that the underlying WebGL implementation support depth textures, either through the WEBGL_depth_texture or WEBKIT_WEBGL_depth_texture extensions. scene.pickPositionSupported is returning false because this extension is missing. You can verify this by going to http://webglreport.com/ and looking at the list of extensions; I have both of the above listed there. There is nothing you can do in your code itself to make it suddenly return true, it's a reflection of the underlying browser.
That being said, I know for a fact that Chrome supports the depth texture and it works on Windows 10, so this sounds like a likely video card driver issue. I full expect downloading and installing the latest drivers for your system to solve the problem.
As for rayIntersection, from a quick look at your code I only expect it to be defined if the mouse is actually over the globe, which may not always be the case. If you can reduce this to a runnable Sandcastle example, it would be easier for me to debug.
OK. So it turned out that I had a totally messed up Cesium environment. I had to delete it and reinstall it in my project (npm install cesium --save-dev). Then I had to fix a few paths and VOILA! It worked. Thanks to both of you for all your help.

Extending JavaScript Classes for use on Canvas

I am working on a project to help me gain a better understanding of JavaScript and building applications with it. I am currently making a game utilizing createjs. I'd like to extend the Shape "class" by adding some additional methods to it but can't seem to get my head around the issue.
I am not getting any runtime errors by this approach, however I think it's failing silently at a particular point.
My Subclass:
ShipGFX.prototype = new createjs.Shape();
function ShipGFX()
{
createjs.Shape.apply( this );
this.draw = function()
{
var g = this.graphics;
g.clear();
g.setStrokeStyle( 1 );
g.beginStroke( createjs.Graphics.getRGB( 0x00ff00 ) );
g.beginFill( createjs.Graphics.getRGB( 0x00ff00, 0.5 ) );
g.moveTo( 0, 0 );
g.lineTo( -5, -5 );
g.lineTo( 10, 0 );
g.lineTo( -5, 5 );
g.lineTo( 0, 0 );
g.endFill();
}
}
Where it's used:
var shape = new ShipGFX();
shape.draw();
So the console logs no errors and I can even log via the draw command. I think the issue is scope of this.graphics even though it doesn't fail there either. Is it a matter of scope? Is the this.graphics a reference to the prototype instance (if I understand that correctly). I'd ideally like to use Class-js as I have a better understanding of how it works but I can't even get this way to work.
Any input would be great. Thank you.
The reason why this was failing silently was because little did I realize that the draw function was preexisting in the createjs.Shape APIs. Changing the name to "render" solved my issue.

non-concatenated dat.gui source with require.js. Customising, or templating dat.gui

Please excuse the SEO friendly title, but I would like to make the problem I am currently solving as accessible as possible. For those of you who are looking to customise the look and feel of dat.gui, you need to download the source and include it using require.js using the instructions here: https://code.google.com/p/dat-gui/.
And now my question.
I am working on a project that requires building a UI with heavy live integration with Javascript (I'm using three.js) and I have decided to modify dat.gui to create this ui; with a view to soon integrate it with backbone.js as a collection of views.
I wish to switch to use the dat.gui source files to edit the styling
To start, I switched over from the concatenated dat.gui.min.js, to the source using the instructions in the link above. I put the whole source in its own folder within my libraries folder, and placed the main.js file the require.js err... requires within the "src" folder. I did this due to linking dependencies within dat.gui's "GUI.js".
Everything seems to link up properly, and I am using essentially the same code as I did before to create my dat.guis, but I keep getting undefined errors, depending on how I change the gui variable either in my original code or in main.js. My understanding of require.js is VERY limited and I feel it is something integral to how it works (and that it's defiantly one of those oh so simple problems for someone with the know how)
Here's my main.js file located at /libraries/dat-gui/src
(this dir also includes text.js)
//This is main.js for using require.js
require([
'dat/gui/GUI'
], function(GUI) {
// No namespace necessary
var gui = new GUI();
});
and here's the bones of my original dat.gui definition code:
////////////////////////////////////////////////DatGui/////////////////////////////////////////////////////
var stageConfigData = function() {
this.scaleX = params.stageWidth;
this.scaleZ = params.stageDepth;
this.spinTheCamera = false;
this.lightIntensity = 1;
this.lightDistance = 0;
this.lightFrontColour = "#ffb752";
this.lightRearColour = "#3535fa";
this.lockCameraToScene = true;
this.tooltype = 3;
this.objectSelect = 'Man';
this.saveJSON = function(){
saveJSON();
};
};
var stageConfig = new stageConfigData( );
var moveConfig = new moveConfigData( );
///I think the problem is linked to defining this variable:
//var gui = new dat.GUI();//works for the minified version
var gui = new dat.GUI();//for non-concatenated
var fstage = gui.addFolder('Stage');
var fcamera = gui.addFolder('Camera');
var ffhouselts = gui.addFolder('Front of House Lights');
var fRearlts = gui.addFolder('Rear Lights');
var sandl = gui.addFolder('Saving and Loading');
fstage.add( stageConfig, 'scaleX', 1, 100, 5).name('Width of stage').onChange( function(){
stage.scale.x = ( stageConfig.scaleX );
});
fstage.add( stageConfig, 'scaleZ', 1, 100, 5).name('Depth of stage').onChange( function(){
stage.scale.z = ( stageConfig.scaleZ );
});
... //there's more but i think it's irrelevant
and the errors i am getting are either:
Uncaught ReferenceError: dat is not defined
or
Uncaught ReferenceError: GUI is not defined
depending on how I mess with those variables and the bit in main.js under //No namespace necessary. I don't understand how namespaces work as I am quite new to javascript as a whole.
Has anyone any ideas? Again, I'd say this is probably one of those real dunce moments, but I would really appreciate the help nonetheless.
Thanks a lot!
When you use require.js method there will be no global object. But you can create it yourself
require([
'dat/gui/GUI'
], function(GUI) {
window.dat = {
GUI: GUI
};
});

Categories

Resources