Jump to content

Impostors and physics trouble


Nubsy
 Share

Recommended Posts

Hello everyone!

First I just want to say that I'm really enjoying the simplicity and ease of use of Babylonjs, and from the topics I've read here, you all are very helpful and more importantly, excited to help.

 

I know this question reeks of not doing my research, but I promise that I have, and I must be missing something. I'm guessing it's probably something small and stupid, because that seems to be my usual problem.

 

My idea was to make a maze. The boundaries of the maze are defined by a 2D array which is traversed to create box meshes in the correct location. I also created a flat box "floor" mesh as the floor, and then what I'm calling a speck. The speck is a small box with no transformations that acts as the parent to the wall boxes and the floor. I would apply a rotation to the speck and everything would rotate with it. (I'm using Temechon's Oimo plug-in and babylon.1.13-beta-debug.js btw).

 

The walls and floor have physics set as:

setPhysicsState({ impostor: BABYLON.PhysicsEngine.BoxImpostor, restitution: 0.5, move: false }); 

And the sphere that goes in the maze has a state of:

setPhysicsState({ impostor: BABYLON.PhysicsEngine.SphereImpostor, mass: 0.1, move: true}); 

However, if I apply a rotation to the parent, the floor and wall meshes rotate, but the ball falls through the floor and lands on the invisible impostor, which has stayed in the original location. (which is the proper behavior, I think)

 

I know about "Quarternion Hell", but even that doesn't seem to work. Either I'm doing something wrong, or again, I'm missing something. Here's what I have so far:

var canvas,	engine,	scene,	camera,	boxSize = 4.0,	rowTileCount = 15,	colTileCount = 20,	mazeWall = [],	mazeFloor = [],	mazeHeight = 60,	mazeWidth = 80,	sphere,	maze = [		[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],		[1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1],		[1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1],		[1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1],		[1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1],		[1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1],		[1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1],		[1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1],		[1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1],		[1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1],		[1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1],		[1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 2, 0, 1],		[1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1],		[1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1],		[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]	];document.addEventListener("DOMContentLoaded", function() {	if (BABYLON.Engine.isSupported()) {		initScene();	}}, false);window.addEventListener("resize", function () {	if (engine) {		engine.resize();	}},false);function initScene() {	/* Canvas, engine, scene, and lights */	canvas = document.getElementById("renderCanvas");	engine = new BABYLON.Engine(canvas, true);	scene = new BABYLON.Scene(engine);	oimo = new BABYLON.OimoJSPlugin()	scene.enablePhysics(new BABYLON.Vector3(0,-9.81,0), oimo);	var light = new BABYLON.PointLight("light", new BABYLON.Vector3(0 - (mazeWidth/2), 5, 0 - (mazeHeight/2)), scene);	var light2 = new BABYLON.PointLight("light", new BABYLON.Vector3((mazeWidth/2), 5, (mazeHeight/2)), scene);	/* Materials... all of them */	var materialSphere = new BABYLON.StandardMaterial("texture1", scene);	materialSphere.diffuseTexture = new BABYLON.Texture("./img/franceball2.jpg", scene);	var materialBox = new BABYLON.StandardMaterial("texture3", scene);	materialBox.diffuseTexture = new BABYLON.Texture("./img/ground.jpg", scene);	/* Floor, sphere (this seems out of place?), and camera (because it relies on sphere) */	speck = BABYLON.Mesh.CreateBox("speck", 0.01, scene);	//speck.rotation.x = Math.PI/8;	speck.rotationQuaternion = BABYLON.Quaternion.RotationYawPitchRoll(0, Math.PI/8, 0);	floor = BABYLON.Mesh.CreateBox("worldFloor", 1, scene);	floor.scaling.x = mazeWidth;	floor.scaling.z = mazeHeight;	floor.position.y -= 1.8;	floor.material = materialBox;	floor.parent = speck;	floor.setPhysicsState({ impostor: BABYLON.PhysicsEngine.BoxImpostor, restitution: 0.5, move: false });	sphere = BABYLON.Mesh.CreateSphere("Sphere", 10.0, 4.0, scene);	sphere.material = materialSphere;	sphere.position = new BABYLON.Vector3(5.1 - ((mazeWidth/2) - (boxSize/2)), 15, 10 - ((mazeHeight/2) - (boxSize/2)));	sphere.checkCollisions = true;	sphere.setPhysicsState({ impostor: BABYLON.PhysicsEngine.SphereImpostor, mass: 0.1, move: true});		camera = new BABYLON.ArcRotateCamera("Camera", 2, 1, 40, sphere.position, scene);	camera.attachControl(canvas);	var createWall = function(id, x, z, type) {		if(type == 1) {			box = BABYLON.Mesh.CreateBox("box", 4.0, scene);			box.position = new BABYLON.Vector3(x - ((mazeWidth/2) - (boxSize/2)), 0, z - ((mazeHeight/2) - (boxSize/2)));			box.material = materialBox;			box.parent = speck;			box.checkCollisions = true;			box.setPhysicsState({ impostor: BABYLON.PhysicsEngine.BoxImpostor, restitution: 0.5, move: false });		}	};	/* Build maze by iterating over maze array */	var id = 0;	for (var r = 0; r < rowTileCount; r++) {		for (var c = 0; c < colTileCount; c++) {			var tile = maze[r][c];			createWall(id, (c*boxSize), (r*boxSize), tile);			id++;		}	}	/* Engine loop */	engine.runRenderLoop(function () {		scene.render();	});}window.addEventListener("keyup", function (event) {	if (event.keyCode === 87) { //up		speck.rotation.z += Math.PI/64;		//sphere.applyImpulse(new BABYLON.Vector3(0,0,2), sphere.position);	} else if (event.keyCode === 65) { //left		speck.rotation.x -= Math.PI/64;		//sphere.applyImpulse(new BABYLON.Vector3(-2,0,0), sphere.position);	} else if (event.keyCode === 68) { //right		speck.rotation.x += Math.PI/64;		//sphere.applyImpulse(new BABYLON.Vector3(2,0,0), sphere.position);	} else if (event.keyCode === 83) { //down		speck.rotation.z -= Math.PI/64;		//sphere.applyImpulse(new BABYLON.Vector3(0,0,-2), sphere.position);	}});

I feel like something like rotating meshes on the fly should be fairly simple, am I mistaken?

 

Thanks for your help and all your hard work!

Link to comment
Share on other sites

Hi Nubsy, welcome !

 

The Oimo plugin is not in the stable version of Babylon for now (the plugin is over and the typescript version is coming soon).

I think you forgot to update the body position of your ground.

 

In my last demo (http://pixelcodr.com/tutos/oimo/game/index.html), I created a custom version of babylon v1.13, is it the one you currently use ? If so, you should have a function mesh.updateBodyPosition().

This function should be used when the mesh position (and/ rotation) has been updated.

 

In your case, in your keyboard handler, you should add : 

speck.rotation.z -= Math.PI/64;floor.updateBodyPosition();

This way, the body (the physical object used by Oimo) will update its position, and all physicals objects will react accordingly.

 

I hope this help :)

 

Cheers !

Link to comment
Share on other sites

Hi Nubsy, welcome !

 

The Oimo plugin is not in the stable version of Babylon for now (the plugin is over and the typescript version is coming soon).

I think you forgot to update the body position of your ground.

 

In my last demo (http://pixelcodr.com/tutos/oimo/game/index.html), I created a custom version of babylon v1.13, is it the one you currently use ? If so, you should have a function mesh.updateBodyPosition().

This function should be used when the mesh position (and/ rotation) has been updated.

 

In your case, in your keyboard handler, you should add : 

speck.rotation.z -= Math.PI/64;floor.updateBodyPosition();

This way, the body (the physical object used by Oimo) will update its position, and all physicals objects will react accordingly.

 

I hope this help :)

 

Cheers !

 

I am using that version of Babylon, yes.

 

That has helped some, but it's still not quite right. So, when it first loads, the ball drops into the maze and bounces slightly, which is perfect. Then upon hitting the arrow keys, the maze moves, but the ball still still stays where it is; the maze moves through it. What I'd like is for it to be in the maze as it moves, and roll with gravity. I know gravity is enabled because it falls. I don't think that the ball should be a child to anything, it should be a free body, right?

 

The other thing that's slightly minor, but possibly relevant is that the ball is just slightly 'in' the floor, rather than on top.

 

Thanks for the help!

Link to comment
Share on other sites

Thank you for your demo and for using my tutorial ;) I hope it helped you a bit !

 

It appears the floor is set to 'move:false'... Therefore, its body won't move at all.

I'm sorry, but I didn't find a way to create such a game (with a static moving floor) with the current version of the plugin. 

 

I will think about it though, and I will answer to this thread if I find anything.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...