Fish Mesh Entry:
Ok, here's the last installment and an actual entry for the fish mesh. The pupose of this was just to show that a mesh can be constructed triangle by triangle without memblocks and you are not just limited to the single shaped primatives. Using this or a similar method you can construct pretty much anything if you can figure out the math and the plotting.
remstart
==============================================================
= Title : DBC Challenge - under water Create Fish Mesh
= Author : latch
= Date : 01/15/2008
= Update : 01/17/2008
= Version: .03
==============================================================
Comments This is an example of how to build a mesh triangle
by triangle without using memblocks. The function
make_fish() will create a mesh that is supposed to
look like a cute little fishy! For moveable fins
and tail I just added a few primatives.
the parameters are:
make_fish(obj,size#,tiers)
obj == the object number the fish will be
size# == the x size of the body (not including tail)
tiers == tiers^2 * 2 = number of polys (triangles)
The minimum tiers is 4. Going above ten is not
a great idea.
I tried to use a very basic method of creating 2
grids - front and back, and then just pinching the
ends together, separating the middle area (z) and
then plotting the x and y with a bit of skewing on
the y for the head and tail. There are better
ways to do this for a shape rounded like a fish,
like multiple ellipse shaped rings, but I wanted
to keep the math as basic as possible for the demo.
I did use a parabola for the head, and that's about
as complex as the math got! The size of the function
is due to the drawing of the triangles and limbs.
The math to place the points is the smallest part.
Building each model can be slow, but if a single
model is built, it can be converted into a mesh
and copies from it will be made much faster using
MAKE OBJECT.
==============================================================
remend
rem =============================================================
rem = SET UP DISPLAY
rem =============================================================
autocam off
set display mode 800,600,32
sync on
sync rate 60
rem =============================================================
rem = MAIN
rem =============================================================
gosub _init
position camera 0,0,-100
direction=1
do
turn object left fish1,.3
turn object left fish2,.3
turn object left fish3,.3
ang#=wrapvalue(ang#+direction)
if ang# = 6 then direction=-1
if ang# = 354 then direction=1
rotate limb fish1,1,limb angle x(fish1,1),wrapvalue(ang#*2),limb angle z(fish1,1)
rotate limb fish2,1,limb angle x(fish2,1),ang#,limb angle z(fish2,1)
rotate limb fish3,1,limb angle x(fish3,1),ang#,limb angle z(fish3,1)
sync
loop
end
rem =============================================================
rem = SUBROUTINES - PROCEDURES
rem =============================================================
_init:
rem fish
fish1=1
fish2=2
fish3=3
fish4=4
rem textures
gosub _textures
rem make fish
make_fish(fish1,40.0,4)
texture object fish1,fish1
position object fish1,-30,0,0
make_fish(fish2,40.0,7)
texture object fish2,fish2
position object fish2,30,0,0
make_fish(fish3,40.0,10)
texture object fish3,fish3
position object fish3,0,-30,0
return
`-----------------------------------------------------------------
_textures:
cls 0
ink rgb(255,0,0),0
dot 0,0
dot 0,1
get image fish1,0,0,2,2
cls 0
ink rgb(255,255,0),0
dot 0,0
dot 1,0
get image fish2,0,0,2,2
cls 0
ink rgb(0,255,0),0
dot 1,0
dot 1,1
get image fish3,0,0,2,2
return
rem =============================================================
rem = FUNCTIONS
rem =============================================================
function make_fish(obj,size#,tiers)
rem make sure the minimum is 4x4
if tiers < 4 then tiers = 4
rem set up vertice plotting variables
xinc#=size#/tiers
yinc#=xinc#/3
zinc#=size#/12.0
tailx#=size#/4.0
taily#=((tiers-1)/2.0)*yinc#
mid=(tiers-1)/2
rem array to hold points
dim verts#((tiers^2)*2,2)
rem go through x and y positions and calculate points for triangles
for y=0 to tiers-1
for x=0 to tiers-1
rem v=vertices for front
rem v2=vertices for back so we only have to run through one set of points
v=x+(y*tiers)
v2=v+tiers^2
rem front side
rem check if we are at the tail
if x=tiers-1
verts#(v,0)=(x*xinc#)+tailx#
verts#(v,1)=taily#
else
rem check if we are at the head
if x <= mid-1
rem upper parabola for the top of the head
rem change the head size by changing 3.5 in (x*xinc#/3.5)
if y > mid
verts#(v,1)=taily#+sqrt(4*(y*yinc#/2)*(x*xinc#/3.5))
verts#(v,0)=x*xinc#/1.5
endif
rem plot the lower parabola for the bottom of the head
if y <= mid
verts#(v,1)=taily#-sqrt(4*((taily#-y)*yinc#/2)*(x*xinc#/3.5))
verts#(v,0)=x*xinc#/1.5
endif
else
rem default x and y
verts#(v,0)=x*xinc#
verts#(v,1)=y*yinc#
endif
endif
rem z values. The logic checks if we are at any edge of the grid
rem and if so, it sets z=0 effectively "pinching" the ends closed
rem if we are not at an edge, the -1.0 pushed the z value outwards
rem towards the viewer (-z) by zinc#
verts#(v,2)=-1.0*(zinc#*((y!0) & (y!tiers-1) & (x!0) & (x!tiers-1)))
rem backside
rem same x and y values, and opposite z values from front grid
verts#(v2,0)=verts#(v,0)
verts#(v2,1)=verts#(v,1)
verts#(v2,2)=0.0-verts#(v,2)
next x
next y
rem make triangles
tri=obj
lmb=0
for y=0 to tiers-2
for x=0 to tiers-2
v=x+(y*tiers)
v2=v+tiers^2
rem triangle 1
x1#=verts#(v,0)
y1#=verts#(v,1)
z1#=verts#(v,2)
x2#=verts#(v+tiers,0)
y2#=verts#(v+tiers,1)
z2#=verts#(v+tiers,2)
x3#=verts#(v+tiers+1,0)
y3#=verts#(v+tiers+1,1)
z3#=verts#(v+tiers+1,2)
rem this check is here to make sure we don't overwrite
rem the object we are assigning to the fish since we reuse
rem and delete the same object and mesh over and over
rem to manage overhead as we go
while object exist(tri)=1
inc tri
endwhile
make object triangle tri,x1#,y1#,z1#,x2#,y2#,z2#,x3#,y3#,z3#
rem the first triangle is the root object of the mesh initially
rem so we don't want to turn it into a limb
if v<>0
make mesh from object tri,tri
inc lmb
add limb obj,lmb,tri
delete object tri
delete mesh tri
endif
rem triangle 2
x1#=verts#(v+tiers+1,0)
y1#=verts#(v+tiers+1,1)
z1#=verts#(v+tiers+1,2)
x2#=verts#(v+1,0)
y2#=verts#(v+1,1)
z2#=verts#(v+1,2)
x3#=verts#(v,0)
y3#=verts#(v,1)
z3#=verts#(v,2)
rem if we successfully created the first triangle, we
rem want to make sure to skip that as an object to
rem manipulate
while object exist(tri)=1
inc tri
endwhile
make object triangle tri,x1#,y1#,z1#,x2#,y2#,z2#,x3#,y3#,z3#
inc lmb
make mesh from object tri,tri
add limb obj,lmb,tri
delete object tri
delete mesh tri
rem back
rem triangle 1
x1#=verts#(v2,0)
y1#=verts#(v2,1)
z1#=verts#(v2,2)
x2#=verts#(v2+tiers,0)
y2#=verts#(v2+tiers,1)
z2#=verts#(v2+tiers,2)
x3#=verts#(v2+tiers+1,0)
y3#=verts#(v2+tiers+1,1)
z3#=verts#(v2+tiers+1,2)
make object triangle tri,x1#,y1#,z1#,x2#,y2#,z2#,x3#,y3#,z3#
inc lmb
make mesh from object tri,tri
add limb obj,lmb,tri
delete object tri
delete mesh tri
rem triangle 2
x1#=verts#(v2+tiers+1,0)
y1#=verts#(v2+tiers+1,1)
z1#=verts#(v2+tiers+1,2)
x2#=verts#(v2+1,0)
y2#=verts#(v2+1,1)
z2#=verts#(v2+1,2)
x3#=verts#(v2,0)
y3#=verts#(v2,1)
z3#=verts#(v2,2)
make object triangle tri,x1#,y1#,z1#,x2#,y2#,z2#,x3#,y3#,z3#
inc lmb
make mesh from object tri,tri
add limb obj,lmb,tri
delete object tri
delete mesh tri
next x
next y
rem make a whole mesh of the body to eliminate the hundreds of limbs
rem just created
make mesh from object obj,obj
delete object obj
make object obj,obj,0
delete mesh obj
rem reset limb count
lmb=0
rem add a tail
tail=obj+1
while object exist(tail)
inc tail
endwhile
make object cone tail,size#/2.0
rem set tail pivot
position object tail,0,-1.0*object size y(tail)/2,0
scale object tail,100,100,10
make mesh from object tail,tail
delete object tail
inc lmb
add limb obj,lmb,tail
offset limb obj,lmb,size#/1.2,taily#,0
rotate limb obj,lmb,0,0,90
delete mesh tail
rem top fin
make object box tail,size#/4,size#/4,zinc#/8
make mesh from object tail,tail
delete object tail
inc lmb
add limb obj,lmb,tail
offset limb obj,lmb,size#/2,taily#*1.8,0
rotate limb obj,lmb,0,0,38
rem left fin
rem set pivot
make object tail,tail,0
position object tail,object size x(tail)/2,0,0
rotate object tail,0,30,45
delete mesh tail
make mesh from object tail,tail
delete object tail
inc lmb
add limb obj,lmb,tail
offset limb obj,lmb,size#/4,taily#,zinc#*-1.5
scale limb obj,lmb,70,70,70
rem right fin
inc lmb
add limb obj,lmb,tail
rotate limb obj,lmb,180,0,0
offset limb obj,lmb,size#/3,taily#,zinc#*1.5
scale limb obj,lmb,70,70,70
delete mesh tail
rem turn culling off because individual triangles only have one direction
rem for their normals no matter how they are rotated as a limb after
rem creting them as a mesh. Otherwise, there will be holes in the mesh
set object obj,1,1,0
endfunction
Enjoy your day.