how to animate a tile in a mesh?

Blitz3D Forums/Blitz3D Beginners Area/how to animate a tile in a mesh?

Abomination(Posted 2008) [#1]
I'm not this far in my game yet (not by a longshot!), but somewhere along the way I need to find a way to animate a tile in a mesh.
The mesh is quite large, since it represents a terrain. The tiles would be waving grass or rippling water etc.
Perhaps I could switch UVs in a singelesurface, or change brushes somehow?
I was hoping there was a function like loadanimbrush(), but there isn't, or is there?
I would sure appreciate if someone could guide me in a doable direction. I don't need full working code (though that would be nice); just some advice on what way would be fast or simple. (simple? yeah right!)
greets.


Cp(Posted 2008) [#2]
maybe you could make a animated gif image and load it into a brush.
I actually forgot whether or not gifs are supported.


D4NM4N(Posted 2008) [#3]
I dont think they are, however you can use animated texture strips in jpg or png format.


Abomination(Posted 2008) [#4]
Yes; but how to apply them to a specific tile?


D4NM4N(Posted 2008) [#5]
By tile im assuming you mean 1 quad (2 triangles) right?
If so, you could;

1) track down those 4 vertices coords and add new surface geometry to texture with the other texture,

or:

2)use 2 texture indexes on the same brush with separate UV sets (however there are only 2 sets of UVs per brush and 1 brush per surface AFAIK so doing this would make lightmapping difficult) This method is not geometry bound like the other so you could use the UVs to position it anywhere you like.


However, i notice you are talking about rippling grass. Why not just use crossplanes with a png alpha texture on certain vertex positions? You could make the system dynamic by using copyentity and freeentity when in and out of camera range/view.

For the copyentity you would use a sourcemesh which never gets freed and is invisible (use hideentity) but copies itself where and when needed.


Abomination(Posted 2008) [#6]
ehm... This is the beginners area, wright? Ha!
Thanks D4NM4N; I sure don't understand everything of your advice, but enough to get me going.
Except for the first one, those methods would not be something I would have thought of myself.


D4NM4N(Posted 2008) [#7]
(Sorry :)

For the grass crossplane bit, it is simply an X shaped wall mesh, double sided with a texture on it. For testing, just use a cube for now.
Unfortunately, the following is out of my head and i am not on a windows machine at the moment, so cannot test it for you, but it should work, (may need a syntax correction or two :)

It would be loaded with something like:
;set color+alpha+mipmap on any texture with grass in name (must be 32bit PNG or TGA!)
texturefilter ("grass",1+2+8)   

;load the textured X mesh
global sourcegrass=loadmesh("mygrass.png")   

;enable backfaces so both sides of all 4 triangles of the crossplane are visible from both sides.
entityfx (sourcegrass, 16)  



Then using an array or custom type to store the data something like:
(assuming you use custom types rather than an array)

type Tgrass
    field handle%
    field X#
    field Y#
    field Z#
end type
(arrays are faster tho but not as 'pretty' :)


You obviously need to fill the above structure with some virtual 'grass' objects (each one will be a desired location). This structure could be filled in many ways, for example;
- by simply hard-coding them(yuck!),
- placement maps (a hidden image with different colors for different things)
- using a placement script from a level or terrain editor,
- by 'intelligent' mesh analysis of the terrain itself (ie. record pos. of 'random verticies that have the vertexcolor green').

Either way, object creation would be done by:
g.Tgrass=new Tgrass
   g\handle=0   ;(no need for a value here yet, this will store the copy's pointer or 'handle')
   g\x = 342    ;<--example coords
   g\y = 32
   g\z = 100



Then in your main loop add the dynamic placement code. I have used a reference pivot here for simplicity but using maths (*may*) be faster :/

Something like this in the main loop:
;create our reference object
refpoint=createpivot()

;iterate through all "grass" objects
for g.Tgrass = each Tgrass;
    
    ;position reference at position stored in the object "g" of type Tgrass 
    positionentity refpoint(g\x, g\y, g\z)

    ;work out how far away from camera the position of the reference is
    if entitydistance(camera,refpoint) < visiblerange then
         ;if it doesn't already exist make an "instance" and position it 
         if not g\handle then 
             g\handle=copyentity(sourcegrass)
             positionentity (g\handle, g\x, g\y, g\z)
         endif
    else
         ; if not in range and an instance exists then delete it, freeing precious resources!.
         if g\handle then
               freeentity g\handle : 
               g\handle=0  ;<---important, freeentity does not delete the pointer's value
         endif
    endif

next

;delete the refpoint (important!)
freeentity refpoint : refpoint = 0


Hope this helps and works ok, as i say, i cant test it for you im afraid. However the 'theory' is there to give you some ideas.

ps: This same kind of system can be used for pretty much anything, monsters, items, buildings etc..


Abomination(Posted 2008) [#8]
Yes; this really helps. Thanks for giving this so much thought. -an explanation even I could understand- :0
I will try to implement this 'theory' in my 'terrain-mesh'.
sure hope it's fast enough; there is a LOT of grass in my game. ;)


D4NM4N(Posted 2008) [#9]
Ive just realised i used the BMAX syntax standard ie, "g.handle" rather than "g\handle"

Only use . when assigning the type object (eg. "g.Tgrass = each") for field access you need to use "\" not a "."

Sorry about that, but im sure you worked it out ;)