Saving / Loading / Picking B3D model?

Blitz3D Forums/Blitz3D Programming/Saving / Loading / Picking B3D model?

Guy Fawkes(Posted 2015) [#1]
Hi all, been a long time & I'm back for the most part. Been working a little in Three.js (GREAT library), but I've decided to finish what I started. My 3D Level Editor. I have a quick question if you all do not mind. :) How can I save a B3D model WITH its' animations / textures all intact, load it into a small demo, and pick it while it's animating?

I need something simple.

Thank You!

~GF


Matty(Posted 2015) [#2]
Hmm. Saving an animated mesh i think cant be done with native commands - but i think third party libraries exist.

Also picking a mesh on an animation frame beyond the first is also not possible with the native pick commands but i think a third party solution or a workaround may exist for that as well.

Those are some of the long standing and known limitations of blitz 3d.


RemiD(Posted 2015) [#3]

How can I save a B3D model WITH its' animations / textures all intact


Maybe with http://www.blitzbasic.com/codearcs/codearcs.php?code=1794


and pick it while it's animating


If you pick a skinned animated mesh, only the tpose mesh will be recognized.
A way to do this is to attach body parts with similar shapes to the appropriate joints and set their alpha to 0 and pick these body parts which will turn move will the animated skeleton (joints).


Guy Fawkes(Posted 2015) [#4]
What about attaching planes to the bones or something?...


RemiD(Posted 2015) [#5]
By "body parts" i mean shapes/meshes. Since you can't get the shape of a skinned animated mesh during an animation, you have to attach separate shapes to the appropriate joints (each shape being a child of a joint) and when the skeleton (joints) will animate the separate shapes will turn move with the skeleton (joints).
(by joints i mean "bones")

Another way to get the shape of a skinned mesh during an animation (at a specific frame/time) is to calculate it by code by emulating Blitz3d animation system. Determine the shape at this frame/time depending on each joint orientation position and the influence of each joint over each vertex. Then you could recreate the pose of the skinned mesh and be able to set it as pickable (entitypickmode(mesh,2)) and use linepick on it. Doable but not easy.


Guy Fawkes(Posted 2015) [#6]
Well crap.. That's what I was afraid of. What I meant by plane is attach an invisible plane to each vertex, make it 1x1x1 so it's just big enough to pick. or a sphere even.


RemiD(Posted 2015) [#7]
If the mesh is not rigged not skinned (no influences of some joints over some vertices), created with loadmesh or createmesh, you can get the position of each vertex and put a little quad mesh to illustrate its position and be able to select it and be able to position it as you want.
But if the mesh is rigged skinned (influences of some joints over some vertices), created with loadanimmesh, you can't get the position of each vertex other than when it is in the tpose.

The remaining approach would be to emulate Blitz3d animation system (how the position orientation of a joint modifies the position of an influenced vertex) Not sure if this is fast enough to calculate this by code for thousands of vertices.


Matty(Posted 2015) [#8]
You can get the position of the bones if that is good enough and estimate the position of the 'mesh' by assuming each pair of bones is joined by a cylinder of 'n' thickness....probably the most accurate for the least effort.


RemiD(Posted 2015) [#9]
Yes you could attach cylinders to joints it is similar to attach bodyparts shapes to joints but then you would not be able to pick the animated mesh precisely, but this is good enough if the goal is to determine if a rigged skinned animated mesh has been hit by a projectile (after a collision or a linepick).


Guy Fawkes(Posted 2015) [#10]
What about putting an invisible cube the size of the mesh plus 1 around the object itself and just pick that instead?


RemiD(Posted 2015) [#11]
If you don't care about accuracy, yes you can do that. It depends on what you want to achieve...


Guy Fawkes(Posted 2015) [#12]
Well. I just basically wanna use polygonal collision to pick an animated mesh.. A DECLs would be nice...


Guy Fawkes(Posted 2015) [#13]
Anyone? :(


RemiD(Posted 2015) [#14]
We already gave you 3 different ways to pick a rigged skinned animated mesh :
->approximate : use different cubes/cylinders and set each cube/cylinder as a child of the appropriate joint.
->precise but requires the recreation of the mesh in separate body parts : use different body parts and set each body part as a child of the appropriate joint.
->precise and will work with any mesh : emulate Blitz3d animation system to calculate the shape (pose) of the mesh depending on each joint position/orientation and the influences of each joint over some vertices.

Now just do some tests and see which approach is good enough for your tool/game....


Bobysait(Posted 2015) [#15]
As far as I remember, you're maybe the last person I would help on this forum, but ... I also know that whatever I explain, as long as I don't give the fully functionnal code, you won't be able to make it :)

So : this is the "How To" for animated scene loaded with LoadAnimMesh :

- Create a secondary function that will :
 1 / load the scene with loadanimmesh
 2 / read the b3d file and dump the vertices weight and bones ID
     It's pretty simple actually, the b3d format is really easy to parse.
     read chunk
          read size
              select chunk
                  if texs skip
                  if brus skip
                  if node -> read entity name then store position
                       if mesh ->
                             read vrts (one for all surface in the mesh)
                                 -> store the bone ids and weights
                             read tris (one per surface)
                             map the triangle vertex indices with real vertex indices
              end select
 3 / store the data in a structur (array/type...)
 4 / use a structur to store the scene pointer (to use it later while picking geometry)

When picking the geometry, create a secondary function that will :
 1 / launch the "linepick"/"camerapick" function
 2 / parse all "special pickable" geometry with your own pick function
-> the picking function must return the picking distance or -1.0 if failed
 3 / if the distance is further, don't care about it and continue.
  if the distance is nearer, then temporarilly store the data required (entity, surface, triangle, x,y,z, nx,ny,nz ...)
 4 / return the nearest result.

The picking function works like this :
 - assert entity is a mesh
 - 0/ initialize variables :
        current distance = -1.0
        current surface
        current triangle
        current normal ( vector )
        current pos ( vector )
 - 1/ for all surfaces of the mesh
 - 2/    for all vertices of the surface
 - 3.a/     temporary store vertex pos
 - 3.b/     for each bone'IDs stored for this vertex in the previous structur
 -          temp vertex pos += vertex* Bone Matrix * Bone weight
 - next
 - 4/    for all triangles of the surface, use the temp vertex pos
         -> use a line/triangle intersect function
         if test succeed:
            if current distance=-1
                current distance = tested distance
                register current normal, pos, triangle
            elseif current distance > tested distance
                current distance = tested distance
                register current normal, pos, triangle
      if current distance >0
          return current distance
    return -1.0


Here it is. not that hard isn't it ?

Hope you 'll make something usefull of this


Oh ... by the way, I forgot to mention :
-> you can also use the blitz3d sources to recompile it with a working function that cares about the bones ^_^


ps : a decls ?
it's just a txt wrapper to map external dll functions... it is useless unless you don't have a dll with the stuff you need in it :)

but if you just want a decls, I'm in a good day

.lib "animated_picking.dll"
LinePickAnimatedMesh%(x#,y#,z#, vx#,vy#,vz#,radius#) : "_linepickANM@28"



You're welcome


RemiD(Posted 2015) [#16]
Hello Bobysait, :)


you can also use the blitz3d sources to recompile it with a working function that cares about the bones


Good idea, have you done it ? Does it work correctly ? Can you share the upgrade ? (even if it is for some money)


Bobysait(Posted 2015) [#17]
I don't work on blitz3d anymore since I have finished my Blitz3d-like blitzmax engine (but I downloaded the source and compiled them just ... you know ... for experience... So it's something that could be done, but ... not by me).
Then, does it really worth the time cost ? not sure of that, blitz3d is really a dead dx7 engine, and as pointed above, I don't need blitz3d at all, and I learnt to like blitzmax for what it is : its much more object oriented language, the maxgui module, and the massive amount of Bruceys' modules
I just come on the blitz3d section for fun, help, etc ...

I quite never come on blitzbasic by the way, once in a month or two.


ps : And to be true, the last time I required help from here was years ago ... and I answered my own questions, so I'm really just here for fun actually, but, I maybe come back later for selling stuff ... or not ... :)


RemiD(Posted 2015) [#18]
@Bobysait>>Ok ! Good luck with your endeavours.