[bb] AddMeshToSurface by sswift [ 1+ years ago ]

Started by BlitzBot, June 29, 2017, 00:28:43

Previous topic - Next topic

BlitzBot

Title : AddMeshToSurface
Author : sswift
Posted : 1+ years ago

Description : This function allows you to add a single surface mesh to a specific surface of another mesh.

This is extremely useful for optimizing your levels, because in Blitz, each surface you have affects your framerate significantly.

A surface is a collection of vertices within a mesh, and each mesh always has one surface.

So say you have a forest.  If each tree were a seprate entity, you might have 100 surfaces!  That's bad.  In fact, if each tree uses two textures, one for the trunk, and one alpha mapped for the leaves, each tree might have TWO surfaces!  That's even worse.

So what you should do is you should combine surfaces from diffrent entities which use the same texture into a single surface in a single entity.

For example, let's use that forest example again.  If your trees are made from a solid trunk, and an alpha mapped top, then you should combine all your trees into one mesh with two surfaces, and put all the trunks in the first surface, and all the tops in the second.

However, because of the way alpha is sorted in Blitz, it might be better to keep the tops of the trees as seprate entites and just combine the trunks.  You'll have to decide what is best for you.

You can also combine CLUMPS of trees into meshes, that way you can autofade out whole sections of forest for additional speedus.

Using that last method I was able to render a world with 50,000 2 poly trees on a terrain on realtively crappy hardware at a decent rate of speed.  Such a feat would be impossible if they were seprate entities.

Anyhow, here is the code.  Hope you find it useful!


Code :
Code (blitzbasic) Select
; -------------------------------------------------------------------------------------------------------------------
; This function copies a mesh with a single surface to a specific surface of another mesh.
;
; The function can optionally offset the mesh within the destination mesh as it copies it.
; The last six parameters may be omitted when calling the function if no transformation is desired.
; -------------------------------------------------------------------------------------------------------------------
Function AddMeshToSurface(SrcMesh, DestMesh, DestSurface, Voffsetx#=0, Voffsety#=0, Voffsetz#=0, Vpitch#=0, Vyaw#=0, Vroll#=0, Vscalex#=1, Vscaley#=1, VscaleZ#=1)

; Determine if we can optimize the mesh copying.
TransformVertices = True
If (Vpitch#=0) And (Vyaw#=0) And (Vroll#=0)
TransformVertices = False
EndIf


; Make sure there's a surface to copy, because the mesh might be empty.
If CountSurfaces(SrcMesh) > 0

SrcSurface = GetSurface(SrcMesh, 1)

DestVerts  = CountVertices(DestSurface)
SrcVerts   = CountVertices(SrcSurface)

; If we need to transform the vertices in a complex way...
If TransformVertices

; Do slower copy method because we need to rotate the vertices.

; Create a pivot to do the transformations with.
ThisPivot = CreatePivot()
PositionEntity ThisPivot, Voffsetx#, Voffsety#, Voffsetz#, True
RotateEntity ThisPivot, Vpitch#, Vyaw#, Vroll#, True
ScaleEntity ThisPivot, Vscalex#, Vscaley#, Vscalez#

; Copy all the vertices from the source mesh to the destination surface.
For VertLoop = 0 To SrcVerts-1

Vu#  = VertexU#(SrcSurface, VertLoop)
Vv#  = VertexV#(SrcSurface, VertLoop)
Vw#  = VertexW#(SrcSurface, VertLoop)
Vr   = VertexRed(SrcSurface, VertLoop)
Vg   = VertexGreen(SrcSurface, VertLoop)
Vb   = VertexBlue(SrcSurface, VertLoop)

TFormPoint VertexX#(SrcSurface, VertLoop), VertexY#(SrcSurface, VertLoop), VertexZ#(SrcSurface, VertLoop), ThisPivot, 0
Vx# = TFormedX#()
Vy# = TFormedY#()
Vz# = TFormedZ#()

TFormNormal VertexNX#(SrcSurface, VertLoop), VertexNY#(SrcSurface, VertLoop), VertexNZ#(SrcSurface, VertLoop), ThisPivot, 0
Vnx# = TFormedX#()
Vny# = TFormedY#()
Vnz# = TFormedZ#()

AddVertex(DestSurface, Vx#, Vy#, Vz#, Vu#, Vv#, Vw#)
VertexNormal(DestSurface, VertLoop+DestVerts, Vnx#, Vny#, Vnz#)
VertexColor(DestSurface, VertLoop+DestVerts, Vr, Vg, Vb)

Next

FreeEntity ThisPivot

Else

; Do the fast copy.
; Fast copy can do offset and scaling, but not rotation.

; Copy all the vertices from the source mesh to the destination surface.
For VertLoop = 0 To SrcVerts-1


Vx#  = VertexX#(SrcSurface, VertLoop)
Vy#  = VertexY#(SrcSurface, VertLoop)
Vz#  = VertexZ#(SrcSurface, VertLoop)
Vu#  = VertexU#(SrcSurface, VertLoop)
Vv#  = VertexV#(SrcSurface, VertLoop)
Vw#  = VertexW#(SrcSurface, VertLoop)
Vnx# = VertexNX#(SrcSurface, VertLoop)
Vny# = VertexNY#(SrcSurface, VertLoop)
Vnz# = VertexNZ#(SrcSurface, VertLoop)
Vr   = VertexRed(SrcSurface, VertLoop)
Vg   = VertexGreen(SrcSurface, VertLoop)
Vb   = VertexBlue(SrcSurface, VertLoop)

AddVertex(DestSurface, (Vx#*Vscalex#)+Voffsetx#, (Vy#*Vscaley#)+Voffsety#, (Vz#*Vscalez#)+Voffsetz#, Vu#, Vv#, Vw#)
VertexNormal(DestSurface, VertLoop+DestVerts, Vnx#, Vny#, Vnz#)
VertexColor(DestSurface, VertLoop+DestVerts, Vr, Vg, Vb)

Next

EndIf


; Copy all triangles from the source surface to the destination surface.
SrcTris  = CountTriangles(SrcSurface)
For TriLoop = 0 To SrcTris-1

V0 = TriangleVertex(SrcSurface, TriLoop, 0)
V1 = TriangleVertex(SrcSurface, TriLoop, 1)
V2 = TriangleVertex(SrcSurface, TriLoop, 2)

AddTriangle(DestSurface, V0+DestVerts, V1+DestVerts, V2+DestVerts)

Next

EndIf


End Function


Comments :


ryan scott(Posted 1+ years ago)

 >I m a little confused about AddMeshToSurface.>>If I have 20 enemies on screen at once that are identical to each >other,>can I use AddMeshToSurface to speed up rendering?>>If thats the case, Im pretty unclear how I would do that with your >code.   any hints?  Or, is this more for static objects, because they end >up being tied to each other somehow?You should only really combine meshes if you need to, and generally you only need to for static objects.  I would not recommend doing it for enemies, unless you are doing something crazy and have a hundred onscreen at once, and they're all low poly. Particles are an exception to the rule, as there are generally tons of them, but you should use a custom particle system for that as there's no sense in recreating triangles and you don't need to copy normals and stuff.And keep in mind that combining meshes removes the ability to do individual collision detection on them.  You could use a pivot as an "impostor" for that though.>Is it sort of like you could have 1 master entity with its mesh, and >the>other entities rather than having their own mesh, point to the master entity?You have one mesh, and if your other entities are made from the same mesh you'd just add as many copies of it as you need to the main mesh.  But keep in mind that meshes take up video ram, whereas copies of entities do not.  Copies of entities use just one copy of a mesh in video ram.I recommend you only use addmesh to surface for combining things like trees or buildings that are near eachother.


GW(Posted 1+ years ago)

 Why would this command be more usefull that Addmesh() which is 100X faster?


GW(Posted 1+ years ago)

 ..


sswift(Posted 1+ years ago)

 Because addmesh does not allow one to add a mesh to a specific surface in a mesh, and may create additional surfaces.


Stevie G(Posted 1+ years ago)

 Also, Sswifts code allows you to rotate and position the mesh prior to adding it - which is quite handy.


sswift(Posted 1+ years ago)

 Yes, for example, if you wanted to create a clump of trees with addmesh, you would have to:meshcopytranslatemeshaddmeshfreeentityIs that faster than my function?  I'm not sure.  Now add random rotation and scaling to the mix.  Still faster?  Again, I'm not sure.  But it seems likely that creating and freeing hundreds of meshes just might not be faster than simply adding new vertices to a mesh.


Wings(Posted 1+ years ago)

 This is awsome thanks.To bad i dint find this 2 yars ago.Now i can have 32000 trees loaded into gpu at same time.and still have 60 fps.


_PJ_(Posted 1+ years ago)

 <div class="quote"> Yes, for example, if you wanted to create a clump of trees with addmesh, you would have to:meshcopytranslatemeshaddmeshfreeentityIs that faster than my function? I'm not sure. Now add random rotation and scaling to the mix. Still faster? Again, I'm not sure. But it seems likely that creating and freeing hundreds of meshes just might not be faster than simply adding new vertices to a mesh.  </div>Thanks, Sswift. I find your code is certainly a lot easier to work with and is more manageable than Copying AddMesh and Freeing. Speedwise, it seemed to perform adequately but I've only used it for <30 meshes, Couldn't comment on which way is faster yet it works :)