Jump to content

How to rotate mesh A slowly to match orientation of mesh B


georage
 Share

Recommended Posts

I may be doing this wrong, so tell me if you have a better idea for a solution to my problem.

I am creating a toy hockey game and my toys keep falling over smashing into each other and the puck. 

My theory was to use a upright null player (positioned under the ice and therefore invisible to the viewer) as the correct orientation. I would check the orientation of the real player, and if he was on his side I would stop his x,y,z velocity and SLOWLY rotate him to match the null player orientation. Once his position is upright (like upon mesh creation) he will resume his chasing of the puck.

Make sense? Or does my solution sound goofy?

In this playground, how would you make body2 rotate slowly to match the rotational value of body1?

http://www.babylonjs-playground.com/#3HNIJ#7

Thanks for any tips! Having fun with this.

 

Link to comment
Share on other sites

The playground is acting weird after SAVE.  Sometimes it goes to an address WITHOUT the #? fragment identifier on it.  Folks like me panic, thinking they lost their SAVE.... but really, just need to put the new #? at the end, and it's there.  Scary.

ANYway, let's start with this, Geo-man.

http://www.babylonjs-playground.com/#3HNIJ#10

Easier makePlayers(), eh?  And @Deltakosh's animation-to-upright is excellent, because it doesn't care if the player fell over on the X axis, or the Z axis, or a combination.  It just works to make the player upright.  Perfect!

But notice your pivot point?  It really should be at the center of the feet, and not the center of the body.  So, should we consider making the FEET be the parent?  (in our new makePlayer func)  Ideally, the feet cylinder should be just as tall as it is wide, but their are work-arounds.  We can offset the pivot point on the feet... somewhat, and still look natural.

Thoughts?  G... are you ready to both use DK's animation (but on feet instead of body), and adjust makePlayer() so that feet is the parent?  Can ya handle it?  Later, when you have multiple players tipped-over on the ice, some of them partially tipped-back up, some of them not so, some almost comletely recovered... we will "iterate" thru the players array, using the render loop, so that we are "servicing" each player who is not standing upright, yet they all maintain their current "uprightState" or similar thing. 

For example, in makePlayer(), (after you make feet be the parent) you might want to set feet.uprightState = 1;  If player is fallen, you change his/her uprightState = 0;  The "iterator" might loop thru players[] and check each player's .uprightState.  If 1, ignore it.  If <1... service the recovery process.

With me?  I hope so.  Help is nearby.  :)  Thanks for the easy/cool animator, DK!

PS:  http://www.babylonjs-playground.com/#3HNIJ#11   Check out line 43.  SetPivotMatrix!  We moved body's pivot point downward... and thus in line 42, we needed to lower the player itself, too.  But now we are pivoting around a better point.  So, in the other PG with the makePlayer, you can use a setPivotMatrix to move all the body pivot points to the feet... and thus you need not change parenting. 

Link to comment
Share on other sites

http://www.babylonjs-playground.com/#3HNIJ#13

Trying to mix DK's rotater with the makePlayer() func.  Unfortunately, my makePlayer() uses .rotation and not .rotate.  DK's animater uses the body's .rotationQuaternion.... but it doesn't exist without using .rotate or by somehow MAKING one.  I make one in line 26, but it is causing DK's animation to "snap" into place.  Still figging.  :)  body1 on the left, body2 on the right.

@adam, over in another thread, @georage has been using physics engines for puck-drop and stick-collisions testing, and both engines have been failing him due to puck-thru-floor hassles.  I think G had to leave the physics engines behind for now, just because they were getting in the way of progress.

Link to comment
Share on other sites

Hey, thanks for all the help Wingnut and DK (and Adam). You guys rock. 

I have not figured out how to use the render loop correctly on the playgrounds, but I have the "game" in semi-working mode ... right now I just have one toy player chasing a puck and knocking it around. 

http://104.196.110.24/pucky/

I will figure out how to integrate DK's idea and the makePlayer function! Nice tips from everyone!

I am happy enough with Cannon as a physics engine at the moment ... in my testing the puck stays inside the glass most of the time, and I can make the glass higher if I have to, but it obscures the view so I kept it kinda low.

 

 

 

Link to comment
Share on other sites

UPDATE: I've managed to get the makePlayer function working from an external file. Very nice! Thanks again for the help.

I've also managed to set my collisions up in a foreach loop, which is nice.

scene.meshes.forEach(function(m) { m.checkCollisions = true; });

How would I select only meshes that begin with a certain prefix like "wall_" instead of every mesh in the scene?

Also, is it possible to set up impostors in a foreach loop?

For example, I have many players I will eventually set up, and it would be nice to do them all in a loop like I did the collisions above. All the players are pushed onto the players array, so I can loop through the array easily enough, but how do I reference each so they have a unique identifier?

players.forEach(function(m) {
                    ???.physicsImpostor = new BABYLON.PhysicsImpostor(???, BABYLON.PhysicsImpostor.CylinderImpostor, { mass: 5, restitution: notBouncy, friction: slippery }, scene);
                    );

Thanks for any tips! I still haven't been able to get my little hockey dude's to stay upright but I will turn to that next.

 

Link to comment
Share on other sites

Ahh, I like THIS picture of you MUCH BETTER, G-man!  :)

Let's see... http://playground.babylonjs.com/#VGPA2#1

I tried the tags system but it didn't work for me.  (likely my fault).  Test code remarked out.

Pretend line 20 is your makeAllPlayers() func.  Line 24 adds a property to each box called isBox.  It is a type Boolean and thus true/false - sometimes called a flag.

I also push all boxes into the allboxes array, and line 37 starts an iteration through that array, scaling all the x to 5.  Line 39 shows a physics setting that COULD be done, but consider setting your physics on each box/player as it is created.... in your makePlayer func.  But you are certainly welcome to re-iterate through allboxes [or all players] as many times as you like.

Now let's head to line 42.  Here, we are using scene.meshes as our array to iterate-thru, and we happen to know that there are 20 spheres, and THOSE we want to make tall, but don't touch our wide boxes.    Line 43... if (!m.isBox) { // it's NOT a box.  Let's make it tall! }  You get the idea.  And you should check into Javascript predicates, too.  Lots written on the web... about those. 

Lines 53 and 54 show that we do indeed have unique names, generated by lines 11 and 21... which are inside loops that are NOT forEach loops, but instead FOR loops.  Sometimes there is great advantage to using FOR instead of forEach... like the handy 'i' variable in ours.  I append that indexer onto the sphere and box names... and that way, they each have a unique name.  You could use scene.getMeshByName("box_13").  The Babylon Scene class object is PACKED with goodies... enough power to scare the dog!  Get to know it.  It will become your best friend.  :)

Yeah, I know what you're going to say next.  You don't want sequential numbers, you want player jersey numbers, right?  For this type of thing, you might create a "lookup" table.  OR, in makeplayer(), you could assign a jersey number... by adding a player.jerseyNumber just like we did with box.isBox and sphere.isBox.  Adding flags and extra properties, and even extra functions... to standard JS objects... is sometimes called overloading and you can read all about it in JS forums. 

For example... you might want to add a method (a function) to each player called .reportJerseyNumber().  Inside makeplayer()...

player.jerseyNumber = Math.floor(Math.random() * 90 + 10);  // random number 10-99
player.reportJerseyNumber = function() { return this.jerseyNumber }; // add a func to player

Now you have added power to your player object... and anytime you need the player's jersey number...

var jerseynum = allplayers[4].reportJerseyNumber();

Later, you might go as far as maintaining LOTS of info on each player, and you might try things like var stinkyness = player[7].playerData.jersey.sweatStinkLevel  :)  You might even consider overloading allplayers array.  allplayers.getPlayerByJerseyNumber(43);   Lots of options.  That's what makes JS so cool.

Oh yeah, physics imposters can be told to remain standing upright... with something called constraints.  There's also "springs".  A spring could make the player automatically return to upright, when knocked over.  Physics engines have lots of toys, too.  "Weebles wobble but they don't fall down."  ;)

Lastly, let it be known, that you are asking JS questions... in a BabylonJS webGL forum.  You would probably get better answers about JS, on JS forums.  Ok, hope this helps.  JS predicates might be able to eliminate the IF statement in line 43.  Read read read.  :) (hope I didn't say anything incorrect - sorry if I did)

Link to comment
Share on other sites

Wow! that is really cool. I had heard the term overloading and now I know what it is and how to use it. 

I had already added a jersey number in makePlayer()! you read my mind!

i have done it like this ... 

feet.jerseyNumber = Math.floor(Math.random()*100);

which sounds a little weird, adding a jersey number to feet, but it works after I parent/child the three pieces of the toy to create the player.

lots to digest here, but I think I get it ... thanks again! I will be busy tinkering for a while.

Link to comment
Share on other sites

Hi again.  You might want to have a tour around local superhero @Temechon's tutorial site....  http://www.pixelcodr.com/tutorials.html

He's quite good at game structuring and OOP (object wrangling and sub-classing, just like the BJS framework does, too)

Think about this. 

var player = new Object();

It's not even a mesh or sprite.  It's just a blank JS object.

Then, you start "loading"... 
player.someprop = blah;
player.somefunc = function() { blah blah };  
and then...player.gfx = makeplayer();

Instead of overloading the babylon.mesh object(s) returned from makeplayer(), you actually make your own player class object, and put a babylon.mesh class in its .gfx property.  Interesting way of doing things, eh?

OOP-guy Temechon might even create a generic playerClass, and then have 2 sub-classes from that...  blueTeamPlayer and redTeamPlayer, each having constructors (like a .create() function) on them.  When a class has a constructor, it is often called with the 'new' keyword.  Our standard material is like that.  this.material = new BABYLON.StandardMaterial().

Other classes, like Babylon.Mesh... can do both.  http://www.babylonjs-playground.com/#1UHFAP#5

See line 5?  'new BABYLON.Mesh' ... uses mesh's constructor so it uses the 'new' keyword.... to make a shapeless mesh (used for plotting a shape a bit further below, and could be used as an invisible 'gizmo' or 'handle' on your players) (an invisible yet lightweight master player-parent)

Now look at line 26.  There, we use the same BABYLON.Mesh class, but we call its createGround() func.  CreateGround has no return something; as it's last line of that func... because it doesn't return anything.  Instead it places the result into the scene.meshes array.  Of course, there's also createBox(), createSphere(), etc.   So, 'new' indicates that it is a constructor call and that it returns something to you.  It will take you a little while to master WHEN a function should return something; as its last line, and when it shouldn't, or doesn't need-to.

These createXXX functions are non-constructor functions on the BABYLON.Mesh class, which is an extension/subClass of BABYLON.AbstractMesh, which is an extension/ subClass of BABYLON.Node.  Lights, cameras, and mesh... are all extensions of BABYLON.Node... so it is a "universal" class.  It would contain properties and methods that are universal for ALL camera, lights, and mesh. 

Conversely, AbstractMesh... would contain things just for mesh.  All our lights start with a base class light, and all cameras start with a base class camera or maybe universalCamera.

This is OOP... object oriented programming, or as best it can be accomplished with datatype-wobbly javascript.  OOP is wonderful and results in massive code re-usability.  Your base player class... could be used for all sports players, not just hockey.  So, once you build your base class player, you can re-use it in many sports games. 

This is how Temechon is able to produce game after game with very little programming changes between games.  As you tour around in his tutorials, you may wish to "borrow" a few of his base classes, ;) as he was kind enough to make them public, and he's OOP-smart, so they are good base classes.

Speaking of wobbly dataTyping, Typescript is used because of that... providing stricter dataTYPE checking and regimentation than standard JS. 

Javascript allows things like CreateBox("box_"+i, 1, scene);  We concatenated (+)... a string "box_"... to a numeric integer i.  JS says "that's fine, I know what you want to do".  A Typescript compiler would say "What the heck are you trying there?!  You need to use String(i)"

I'm not very good at OOP, but I sure want to be.  Watch Temechon, and you watch a pro.  Watch the BJS framework's structure, and you are watching OOP pros, too.

Now, are you wondering about all that extends and decorate crap at the top of BJS classes? 

Hell, NOBODY knows what that debris is.  heh.  Maybe you can teach it to me, later.  :)  Sorry for long-winded post.  Just wanted you to visit Temechon and have his knowledge in your pocket, should you need it some day.  A web search for JS Objects and inheritance... should produce good results, too... when you're ready for it.

Addenda:  Superhero @RaananW also has a fine, but somewhat deep game tutorial... that starts at  https://msdn.microsoft.com/en-us/magazine/mt595753 but I don't know if he ever created part 2.  It's ok, there's plenty of good stuff in part 1.

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...