Skip to content

Instantly share code, notes, and snippets.

@dermotbalson
Created October 17, 2015 09:54
Show Gist options
  • Save dermotbalson/e57a0bdebd3c9086eda8 to your computer and use it in GitHub Desktop.
Save dermotbalson/e57a0bdebd3c9086eda8 to your computer and use it in GitHub Desktop.
Tank2
--# Test
--[
function setup()
img=readImage("Platformer Art:Block Grass"):copy(0,50,25,50)
b1=CreateBlock(10,5,5,color(255,255,0),nil,img)
b2=CreateBlock(10,5,5,color(255),nil,img) --b2:setColors(color(100,0,0))
b1.pos=vec3(0,0,100) b1.a=0
b2.pos=vec3(0,0,0) b2.a=40
s=vec3(10,5,5)
dp=1
ap=0.25
camPos,camLook=b1.pos,b2.pos
end
function draw()
background(102, 173, 202, 255)
perspective()
camera(camPos.x,camPos.y,camPos.z,camLook.x,camLook.y,camLook.z)
pushMatrix()
translate(b2.pos:unpack())
rotate(b2.a,0,1,0)
b2:draw()
X,Y,w,h=GetScreenRect(b1,b2,s)
popMatrix()
b2.pos.z=b2.pos.z+dp if b2.pos.z<-300 or b2.pos.z>80 then dp=-dp end
b2.a=b2.a+ap
ortho()
viewMatrix(matrix())
fill(255,255,0,50)
rect(X,Y,w,h)
end
function GetScreenRect(t1,t2,s) --t1 is camera, t2 is target, s is vec3 size of object
--assume target only rotates on y, take larger of x and z size to set rect size
local u=math.max(s.x,s.z)
--get direction and distance
local v=(t2.pos-t1.pos)
local d=v:len()-u/2 --position of t2 is assumed to be its centre, so adjust by 1\2 depth
v=v/d
--get drawing rectangle
local w = u*WIDTH*projectionMatrix()[1]/d/2
local h = s.y*HEIGHT*projectionMatrix()[6]/d/2
--draw our tank
local m = modelMatrix()*viewMatrix()*projectionMatrix()
--m = m:translate(0,0,-d)
local X,Y=(m[13]/m[16]+1)*WIDTH/2, (m[14]/m[16]+1)*HEIGHT/2
return X-w/2,Y-h/2,w,h
end
--]]
--# Test3
function setup()
img=readImage("Platformer Art:Block Brick")
b1=CreateBlock(10,5,5,color(255,255,0),nil,img)
b2=CreateBlock(10,5,5,color(255),nil,img)
b1.pos=vec3(0,0,100) b1.a=0
b2.pos=vec3(0,0,0) b2.a=40
s=vec3(10,5,5)
target=image(WIDTH,HEIGHT)
camPos,camLook=b1.pos,b2.pos
dp,ap=1,0.5
parameter.number("FPS",1,60,60)
end
function draw()
FPS=FPS*0.9+0.1/DeltaTime
background(150)
perspective()
camera(camPos.x,camPos.y,camPos.z,camLook.x,camLook.y,camLook.z)
pushMatrix()
translate(b2.pos:unpack())
rotate(b2.a,0,1,0)
b2:draw()
local X,Y,w,h=GetScreenRect(b1,b2,s)
local img=DrawTarget(X,Y,w,h,b2,b1.pos:dist(b2.pos))
popMatrix()
b2.pos.z=b2.pos.z+dp if b2.pos.z<-300 or b2.pos.z>80 then dp=-dp end
b2.a=b2.a+ap
--ortho()
--viewMatrix(matrix())
--sprite(img,w/2,h/2)
end
function GetScreenRect(t1,t2,s) --t1 is camera, t2 is target, s is vec3 size of object
--assume target only rotates on y, take larger of x and z size to set rect size
local u=math.max(s.x,s.z)
--get direction and distance
local v=(t2.pos-t1.pos)
local d=v:len()-u/2 --position of t2 is assumed to be its centre, so adjust by 1\2 depth
v=v/d
--get drawing rectangle
local w = u*WIDTH*projectionMatrix()[1]/d/2
local h = s.y*HEIGHT*projectionMatrix()[6]/d/2
--draw our tank
local m = modelMatrix()*viewMatrix()*projectionMatrix()
--m = m:translate(0,0,-d)
local X,Y=(m[13]/m[16]+1)*WIDTH/2, (m[14]/m[16]+1)*HEIGHT/2
return X-w/2,Y-h/2,w,h
end
function DrawTarget(X,Y,w,h,t,d)
setContext(target)
background(50)
perspective(45,WIDTH/HEIGHT,0.1,d)
clip(X,Y,w,h)
t:draw()
clip()
setContext()
local XX,YY,ww,hh=math.floor(X),math.floor(Y),math.ceil(w),math.ceil(h)
return target:copy(XX,YY,ww,hh)
end
--# Test5
function setup()
targetColor=color(255,0,0) --target colour
--draw a target image with a red square in the middle on a green background
--we want to count the red pixels
img=image(200,200)
noSmooth()
setContext(img)
background(0,255,0)
fill(targetColor)
rect(50,50,50,50)
setContext()
smooth()
--count yellow pixels ------------------
--create the smallest mesh possible, seems to be a triangle with 2x2 pixels
mm=mesh()
mm.vertices={vec2(1,1),vec2(2,1),vec2(1,2)}
mm.shader=shader(pixelCountShader.vertexShader,pixelCountShader.fragmentShader)
mm.shader.c=targetColor --target colour
mm.shader.w=200 --width of texture
mm.shader.h=200 --height of texture
mm.shader.threshold=3000 --number of pixels required to pass threshold
img2=image(2,2)
mm.texture=img --pass through test image
mm:draw()
-----------------------------------
r,g,b=img2:get(2,2) --this seems to be the best pixel to get
setContext()
print("time=",os.time()-t)
print("Result=",r/255,2500/mm.shader.threshold)
end
function draw()
background(200)
sprite(img,WIDTH/2,HEIGHT/2,300) --draw test image
end
pixelCountShader = {
vertexShader=[[
uniform mat4 modelViewProjection;
attribute vec4 position;
varying lowp vec4 vPosition;
void main()
{
gl_Position = modelViewProjection * position;
vPosition=position;
}
]],
fragmentShader = [[
precision highp float;
uniform lowp sampler2D texture;
uniform vec4 c;
uniform float w;
uniform float h;
uniform float threshold;
varying highp vec4 vPosition;
void main()
{
gl_FragColor=vec4(1.0,1.0,1.0,1.0);
if (vPosition.x>1.0 && vPosition.y>1.0) {
float t=0.0;
for (float x=0.0; x<w; x++)
for (float y=0.0; y<h; y++) {
vec4 p=texture2D(texture,vec2(x/w,y/h));
if (p.r==c.r) t+=1.0;
}
gl_FragColor.a = t/threshold;
}
}
]]}
--# Test6
function setup()
targetColor=color(0,0,255) --target colour
--draw a target image with a red square in the middle on a green background
--we want to count the red pixels
img=image(200,200)
--noSmooth()
setContext(img)
background(0,255,0)
fill(targetColor)
s=200/3
rect(50-s/2,50-s/2,s,s)
setContext()
img2=image(4,4)
setContext(img2)
sprite(img,2,2,4)
setContext()
t=0
for i=1,img2.width do
for j=1,img2.height do
r,g,b=img2:get(i,j)
print(r,g,b)
t=t+b
end
end
print("Result=",t/255/img2.width/img2.height)
end
function draw()
background(200)
sprite(img,WIDTH/2,HEIGHT/2,300) --draw test image
sprite(img2,WIDTH/2,HEIGHT/2,50)
end
--# Test7
function setup()
tank=BuildTank(color(150, 189, 128, 255))
camPos=vec3(0,0,50)
ax,ay=0,0
backgroundColor=color(220)
end
function draw()
background(backgroundColor)
perspective()
camera(camPos.x,camPos.y,camPos.z,0,0,0)
rotate(ay,0,1,0) rotate(ax,1,0,0)
for _,m in pairs(tank) do
m.shader.mModel=modelMatrix()
m.shader.camPos=camPos
m:draw()
end
end
function touched(t)
if t.state~=ENDED then
ay,ax=ay+t.deltaX,ax+t.deltaY
end
end
function BuildTank(col)
local x1,x2,y1,y2,y3,z1,z2
--body of tank
local body=mesh()
local v,t,c={},{},{}
x1,x2,y,z1,z2=-8.25,8.25,6.5,4.5,-4.5 --deck
v[#v+1]=vec3(x1,y,z1) v[#v+1]=vec3(x2,y,z1) v[#v+1]=vec3(x2,y,z2)
v[#v+1]=vec3(x2,y,z2) v[#v+1]=vec3(x1,y,z2) v[#v+1]=vec3(x1,y,z1)
x,y1,y2,z1,z2=8.25,2,6.5,4.5,-4.5 --back
v[#v+1]=vec3(x,y1,z1) v[#v+1]=vec3(x,y1,z2) v[#v+1]=vec3(x,y2,z2)
v[#v+1]=vec3(x,y2,z2) v[#v+1]=vec3(x,y2,z1) v[#v+1]=vec3(x,y1,z1)
x,y1,y2,z1,z2=-8.25,4.5,6.5,4.5,-4.5 --front
v[#v+1]=vec3(x,y1,z1) v[#v+1]=vec3(x,y1,z2) v[#v+1]=vec3(x,y2,z2)
v[#v+1]=vec3(x,y2,z2) v[#v+1]=vec3(x,y2,z1) v[#v+1]=vec3(x,y1,z1)
x1,x2,y1,y2,z1,z2=-11,-8.25,3,4.5,4.5,-4.5 --front #2 angle
v[#v+1]=vec3(x1,y1,z1) v[#v+1]=vec3(x1,y1,z2) v[#v+1]=vec3(x2,y2,z2)
v[#v+1]=vec3(x2,y2,z2) v[#v+1]=vec3(x2,y2,z1) v[#v+1]=vec3(x1,y1,z1)
x1,x2,y1,y2,y3,z1,z2=-8.25,8.25,2,2,6.5,4.5,-4.5 --sides
v[#v+1]=vec3(x1,y1,z1) v[#v+1]=vec3(x2,y2,z1) v[#v+1]=vec3(x2,y3,z1)
v[#v+1]=vec3(x2,y3,z1) v[#v+1]=vec3(x1,y3,z1) v[#v+1]=vec3(x1,y1,z1)
v[#v+1]=vec3(x2,y2,z2) v[#v+1]=vec3(x1,y1,z2) v[#v+1]=vec3(x1,y3,z2)
v[#v+1]=vec3(x1,y3,z2) v[#v+1]=vec3(x2,y3,z2) v[#v+1]=vec3(x2,y2,z2)
x1,x2,y1,z1,z2=-11,8.25,2,-2.5,2.5 --underneath
v[#v+1]=vec3(x1,y1,z1) v[#v+1]=vec3(x1,y1,z2) v[#v+1]=vec3(x2,y1,z2)
v[#v+1]=vec3(x2,y1,z2) v[#v+1]=vec3(x2,y1,z1) v[#v+1]=vec3(x1,y1,z1)
x,y1,y2,z1,z2=-11,2,3,-2.5,2.5 --front bottom
v[#v+1]=vec3(x,y1,z1) v[#v+1]=vec3(x,y1,z2) v[#v+1]=vec3(x,y2,z2)
v[#v+1]=vec3(x,y2,z2) v[#v+1]=vec3(x,y2,z1) v[#v+1]=vec3(x,y1,z1)
body.vertices=v
body:setColors(color(90))
body.texture=MakeBodyTexture()
--tracks
local track,v=mesh(),{}
x1,x2,y1,y2,z1,z2=8.25,8.25,1,2,4.5,2.5 --back right vert
v[#v+1]=vec3(x1,y1,z1) v[#v+1]=vec3(x1,y1,z2) v[#v+1]=vec3(x2,y2,z2)
v[#v+1]=vec3(x2,y2,z2) v[#v+1]=vec3(x2,y2,z1) v[#v+1]=vec3(x1,y1,z1)
z1,z2=-2.5,-4.5 --back left vert
v[#v+1]=vec3(x1,y1,z1) v[#v+1]=vec3(x1,y1,z2) v[#v+1]=vec3(x2,y2,z2)
v[#v+1]=vec3(x2,y2,z2) v[#v+1]=vec3(x2,y2,z1) v[#v+1]=vec3(x1,y1,z1)
x1,x2,y1,y2,z1,z2=7.25,8.25,0,1,4.5,2.5 --back right slant
v[#v+1]=vec3(x1,y1,z1) v[#v+1]=vec3(x1,y1,z2) v[#v+1]=vec3(x2,y2,z2)
v[#v+1]=vec3(x2,y2,z2) v[#v+1]=vec3(x2,y2,z1) v[#v+1]=vec3(x1,y1,z1)
z1,z2=-2.5,-4.5 --back left slant
v[#v+1]=vec3(x1,y1,z1) v[#v+1]=vec3(x1,y1,z2) v[#v+1]=vec3(x2,y2,z2)
v[#v+1]=vec3(x2,y2,z2) v[#v+1]=vec3(x2,y2,z1) v[#v+1]=vec3(x1,y1,z1)
x1,x2,y1,y2,z1,z2=-11,-11,2,3,2.5,4.5 --front right vert
v[#v+1]=vec3(x1,y1,z1) v[#v+1]=vec3(x1,y1,z2) v[#v+1]=vec3(x2,y2,z2)
v[#v+1]=vec3(x2,y2,z2) v[#v+1]=vec3(x2,y2,z1) v[#v+1]=vec3(x1,y1,z1)
z1,z2=-4.5,-2.5 --front left vert
v[#v+1]=vec3(x1,y1,z1) v[#v+1]=vec3(x1,y1,z2) v[#v+1]=vec3(x2,y2,z2)
v[#v+1]=vec3(x2,y2,z2) v[#v+1]=vec3(x2,y2,z1) v[#v+1]=vec3(x1,y1,z1)
x1,x2,y1,y2,z1,z2=-9,-11,0,2,2.5,4.5 --front right slant
v[#v+1]=vec3(x1,y1,z1) v[#v+1]=vec3(x1,y1,z2) v[#v+1]=vec3(x2,y2,z2)
v[#v+1]=vec3(x2,y2,z2) v[#v+1]=vec3(x2,y2,z1) v[#v+1]=vec3(x1,y1,z1)
z1,z2=-4.5,-2.5 --front left slant
v[#v+1]=vec3(x1,y1,z1) v[#v+1]=vec3(x1,y1,z2) v[#v+1]=vec3(x2,y2,z2)
v[#v+1]=vec3(x2,y2,z2) v[#v+1]=vec3(x2,y2,z1) v[#v+1]=vec3(x1,y1,z1)
x1,x2,y1,y2,z1,z2=-9,7.25,0,0,2.5,4.5 --bottom right track
v[#v+1]=vec3(x1,y1,z1) v[#v+1]=vec3(x1,y1,z2) v[#v+1]=vec3(x2,y1,z2)
v[#v+1]=vec3(x2,y1,z2) v[#v+1]=vec3(x2,y1,z1) v[#v+1]=vec3(x1,y1,z1)
z1,z2=-2.5,-4.5 --bottom left track
v[#v+1]=vec3(x1,y1,z1) v[#v+1]=vec3(x1,y1,z2) v[#v+1]=vec3(x2,y1,z2)
v[#v+1]=vec3(x2,y1,z2) v[#v+1]=vec3(x2,y1,z1) v[#v+1]=vec3(x1,y1,z1)
track.vertices=v
track:setColors(color(40))
track.texture=MakeTrackTexture()
local a={body=body,track=track}
for _,m in pairs(a) do
local norm={}
local v=m:buffer("position")
for i=1,m.size,3 do
local v1,v2=v[i]-v[i+2],v[i+1]-v[i+2]
local n=(v1:cross(v2)):normalize()
norm[i],norm[i+1],norm[i+2]=n,n,n
end
m.normals=norm
m=SetLighting(m)
end
print("vertices=",body.size+track.size)
return a
end
function SetLighting(m)
m.shader=shader(TankShader.v,TankShader.f)
m.shader.directDirection=vec4(-1,1,1,0):normalize()
m.shader.ambientColor=color(255)*0.3
m.shader.directColor=color(255)*0.7
m.shader.fog=1000
m.shader.mistColor=backgroundColor
return m
end
function MakeBodyTexture()
local img=image(50,50)
setContext(img)
background(122, 184, 121, 255)
setContext()
return img
end
function MakeTrackTexture()
local img=image(50,50)
setContext(img)
background(110, 104, 102, 255)
setContext()
return img
end
--# Utility
--Utility
function CreateBlock(w,h,d,col,pos,tex,ms) --width,height,depth,colour,position,texture
pos=pos or vec3(0,0,0)
local x,X,y,Y,z,Z=pos.x-w/2,pos.x+w/2,pos.y-h/2,pos.y+h/2,pos.z-d/2,pos.z+d/2
local v={vec3(x,y,Z),vec3(X,y,Z),vec3(X,Y,Z),vec3(x,Y,Z),vec3(x,y,z),vec3(X,y,z),vec3(X,Y,z),vec3(x,Y,z)}
local vert={v[1],v[2],v[3],v[1],v[3],v[4],v[2],v[6],v[7],v[2],v[7],v[3],v[6],v[5],v[8],v[6],v[8],v[7],
v[5],v[1],v[4],v[5],v[4],v[8],v[4],v[3],v[7],v[4],v[7],v[8],v[5],v[6],v[2],v[5],v[2],v[1]}
local texCoords
if tex then
local t={vec2(0,0),vec2(1,0),vec2(0,1),vec2(1,1)}
texCoords={t[1],t[2],t[4],t[1],t[4],t[3],t[1],t[2],t[4],t[1],t[4],t[3],t[1],t[2],t[4],t[1],t[4],t[3],
t[1],t[2],t[4],t[1],t[4],t[3],t[1],t[2],t[4],t[1],t[4],t[3],t[1],t[2],t[4],t[1],t[4],t[3]}
end
local n={vec3(0,0,1),vec3(1,0,0),vec3(0,0,-1),vec3(-1,0,0),vec3(0,1,0),vec3(0,-1,0)}
local norm={}
for i=1,6 do for j=1,6 do norm[#norm+1]=n[i] end end
if not ms then ms=mesh() end
if ms.size==0 then
ms.vertices=vert
ms.normals=norm
if tex then ms.texture,ms.texCoords=tex,texCoords end
else
for i=1,#vert do
table.insert(ms.vertices,vert[i])
table.insert(ms.normals,norm[i])
if tex then table.insert(ms.texCoords,texCoords[i]) end
end
end
ms:setColors(col or color(255))
return ms
end
function AddBlock(w,h,d,col,pos,rot,texture,vertices,texCoords,normals,colors) --width,height,depth,colour,position,texture
local x,X,y,Y,z,Z=-w/2,w/2,-h/2,h/2,-d/2,d/2
local v={vec3(x,y,Z),vec3(X,y,Z),vec3(X,Y,Z),vec3(x,Y,Z),vec3(x,y,z),vec3(X,y,z),vec3(X,Y,z),vec3(x,Y,z)}
local vert={v[1],v[2],v[3],v[1],v[3],v[4],v[2],v[6],v[7],v[2],v[7],v[3],v[6],v[5],v[8],v[6],v[8],v[7],
v[5],v[1],v[4],v[5],v[4],v[8],v[4],v[3],v[7],v[4],v[7],v[8],v[5],v[6],v[2],v[5],v[2],v[1]}
if rot then
m=modelMatrix()
m=m:translate(pos:unpack())
m=m:rotate(rot.x,1,0,0) m=m:rotate(r.y,0,1,0) m=m:rotate(r.z,0,0,1)
for i=1,#vert do vertices[#vertices+1]=m*vert[i] end
else
for i=1,#vert do vertices[#vertices+1]=pos+vert[i] end
end
local tex
if texture then
local t={vec2(0,0),vec2(1,0),vec2(0,1),vec2(1,1)}
tex={t[1],t[2],t[4],t[1],t[4],t[3],t[1],t[2],t[4],t[1],t[4],t[3],t[1],t[2],t[4],t[1],t[4],t[3],
t[1],t[2],t[4],t[1],t[4],t[3],t[1],t[2],t[4],t[1],t[4],t[3],t[1],t[2],t[4],t[1],t[4],t[3]}
for i=1,#tex do texCoords[#texCoords+1]=tex[i] end
end
local n={vec3(0,0,1),vec3(1,0,0),vec3(0,0,-1),vec3(-1,0,0),vec3(0,1,0),vec3(0,-1,0)}
for i=1,6 do
for j=1,6 do
normals[#normals+1]=n[i]
colors[#colors+1]=col
end
end
return vertices,texCoords,normals,colors
end
--# Shaders
--Shaders
TankShader={
v=[[
uniform mat4 modelViewProjection;
uniform mat4 mModel;
uniform vec4 directColor;
uniform vec4 directDirection;
uniform vec4 ambientColor;
uniform float fog;
uniform vec4 mistColor;
uniform vec3 camPos;
uniform float offset;
attribute vec4 position;
attribute vec3 normal;
attribute vec2 texCoord;
varying lowp vec4 vColor;
varying highp vec2 vTexCoord;
void main()
{
gl_Position = modelViewProjection * position;
vTexCoord = vec2(texCoord.x+offset,texCoord.y);
vec4 norm = normalize(mModel * vec4( normal, 0.0 ));
float diffuse = max( 0.0, dot( norm, directDirection ));
vec4 p=mModel*position;
float f = clamp(distance(p.xyz,camPos)/fog,0.0,1.0);
vColor = mix(( diffuse * directColor + ambientColor ),mistColor,f);
vColor.a=1.0;
}
]],
f=[[
precision highp float;
uniform lowp sampler2D texture;
varying lowp vec4 vColor;
varying highp vec2 vTexCoord;
void main()
{
gl_FragColor=texture2D(texture, vec2(mod(vTexCoord.x,1.0),mod(vTexCoord.y,1.0)))*vColor;
}
]]}
LightingShader={
v=[[
uniform mat4 modelViewProjection;
uniform mat4 mModel;
uniform vec4 directColor;
uniform vec4 directDirection;
uniform vec4 ambientColor;
uniform float fog;
uniform vec4 mistColor;
uniform vec3 camPos;
attribute vec4 position;
attribute vec4 color;
attribute vec3 normal;
varying lowp vec4 vColor;
void main()
{
gl_Position = modelViewProjection * position;
vec4 norm = normalize(mModel * vec4( normal, 0.0 ));
float diffuse = max( 0.0, dot( norm, directDirection ));
vec4 p=mModel*position;
float f = clamp(distance(p.xyz,camPos)/fog,0.0,1.0);
vColor = mix(color * ( diffuse * directColor + ambientColor ),mistColor,f);
vColor.a=1.0;
}
]],
f=[[
precision highp float;
varying lowp vec4 vColor;
void main()
{
gl_FragColor=vColor;
}
]]}
--Tile
TileShader = {
v = [[
uniform mat4 modelViewProjection;
uniform mat4 mModel;
attribute vec4 position;
attribute vec2 texCoord;
varying highp vec2 vTexCoord;
varying highp vec4 vPosition;
void main()
{
vTexCoord = texCoord;
vPosition=mModel*position;
gl_Position = modelViewProjection * position;
}
]],
f = [[
precision highp float;
uniform lowp sampler2D texture;
uniform float fog;
uniform vec4 mistColor;
uniform vec3 camPos;
varying highp vec2 vTexCoord;
varying highp vec4 vPosition;
void main()
{
lowp vec4 col = texture2D(texture, vec2(mod(vTexCoord.x,1.0),mod(vTexCoord.y,1.0)));
float f = clamp(distance(vPosition.xyz,camPos)/fog,0.0,1.0);
gl_FragColor = mix(col,mistColor,f);
}
]]}
--# Terrain
--Terrain
function MakeTerrain(pos,width,depth,height,cellSize,smoothness)
local ws,ds=width/cellSize,depth/cellSize
local grid0={}
local rw,rd=math.random(),math.random()
for w=0,ws do
grid0[w]={}
for d=0,ds do
local h=height/2*(1+noise(rw+w*smoothness,rd+d*smoothness))-1
grid0[w][d]=vec3(w*cellSize,h,-d*cellSize)+pos
end
end
local grid={}
for w=0,ws do
grid[w]={}
for d=0,ds do
grid[w][d]=grid0[w][d]
end
end
for w=1,ws-1 do
for d=1,ds-1 do
grid[w][d]=(grid0[w][d-1]+grid0[w-1][d]+grid0[w][d+1]+grid0[w+1][d])/8+grid0[w][d]/2
end
end
--normals are averaged
gn={}
for w=0,ws do
gn[w]={}
for d=0,ds do
if w==0 or w==ws or d==0 or d==ds then gn[w][d]=vec3(0,1,0)
else
gn[w][d]=(GetNormal(grid[w][d],grid[w-1][d],grid[w][d-1])+
GetNormal(grid[w][d],grid[w+1][d],grid[w][d-1])+
GetNormal(grid[w][d],grid[w+1][d],grid[w][d+1])+
GetNormal(grid[w][d],grid[w-1][d],grid[w][d+1]))/4
end
end
end
local v,c,n={},{},{}
col=color(62, 208, 72, 255)
for w=1,ws do
for d=1,ds do
local v1,v2,v3,v4=grid[w-1][d-1],grid[w][d-1],grid[w][d],grid[w-1][d]
local n1,n2,n3,n4=gn[w-1][d-1],gn[w][d-1],gn[w][d],gn[w-1][d]
local c1,c2,c3,c4=col,col,col,col
v[#v+1]=v1 n[#n+1]=n1 c[#c+1]=c1
v[#v+1]=v2 n[#n+1]=n2 c[#c+1]=c2
v[#v+1]=v3 n[#n+1]=n3 c[#c+1]=c3
v[#v+1]=v3 n[#n+1]=n3 c[#c+1]=c3
v[#v+1]=v4 n[#n+1]=n4 c[#c+1]=c4
v[#v+1]=v1 n[#n+1]=n1 c[#c+1]=c1
end
end
local m=mesh()
m.vertices=v
m.normals=n
m.colors=c
m.shader=shader(LightingShader.v,LightingShader.f)
m.shader.directDirection=vec4(0,3,0,0):normalize()
m.shader.ambientColor=color(255)*0.3
m.shader.directColor=color(255)*0.7
m.shader.fog=500000
m.shader.mistColor=backgroundColor
return m
end
function GetNormal(v1,v2,v3)
local a,b=v1-v3,v2-v3
return (a:cross(b)):normalize()
end
displayMode(NORMAL)
function setup()
backgroundColor=color(154, 197, 208, 255)
camPos=vec3(0,100,50)
camLook=vec3(500,50,-500)
camDist,camAngle,deltaAngle=100,0,0.01
terrain=MakeTerrain(vec3(0,0,0),1000,1000,100,10,0.06)
ax,ay=0,0
tank=BuildTank(color(150, 189, 128, 255))
end
function draw()
background(backgroundColor)
perspective()
camAngle=camAngle+deltaAngle
camPos.x,camPos.z=camLook.x+camDist*math.cos(camAngle),camLook.z-camDist*math.sin(camAngle)
camera(camPos.x,camPos.y,camPos.z,camLook.x,camLook.y,camLook.z)
terrain.shader.mModel=modelMatrix()
terrain.shader.camPos=camPos
terrain:draw()
translate(500,50,-500)
for _,t in pairs(tank) do
t.shader.mModel=modelMatrix()
t.shader.camPos=camPos
t:draw()
end
end
--# Terrain2
--Terrain2
function MakeTerrain(w,d,pic,f)
local terrain=mesh()
local img=readImage(pic)
terrain.texture=img
local wn,dn=w/img.width/f,d/img.height/f
terrain.vertices={vec3(0,0,0),vec3(w,0,0),vec3(w,0,-d),vec3(w,0,-d),vec3(0,0,-d),vec3(0,0,0)}
terrain.texCoords={vec2(0,0),vec2(wn,0),vec2(wn,dn),vec2(wn,dn),vec2(0,dn),vec2(0,0)}
terrain.shader=shader(TileShader.v,TileShader.f)
terrain.shader.fog=5000
terrain.shader.mistColor=backgroundColor
terrain.shader.mModel=modelMatrix()
return terrain
end
--# Main
-- Tiger
displayMode(FULLSCREEN)
function setup()
backgroundColor=color(129, 162, 201, 255)
T=Tank()
camPos=vec3(0,10,30)
ax,ay=0,0
da=0.1
end
function draw()
background(backgroundColor)
perspective()
camera(camPos.x,camPos.y,camPos.z,0,0,0)
rotate(ay,0,1,0) rotate(ax,1,0,0)
T.turretAngle=T.turretAngle+0.5
T.gunAngle=T.gunAngle-da
if -T.gunAngle<T.turretMaxAngles[1] or -T.gunAngle>T.turretMaxAngles[2] then da=-da end
T:draw(camPos)
end
function touched(t)
if t.state~=ENDED then
ay,ax=ay+t.deltaX,ax+t.deltaY
end
end
function SetLighting(m)
m.shader=shader(TankShader.v,TankShader.f)
m.shader.directDirection=vec4(-1,1,1,0):normalize()
m.shader.ambientColor=color(255)*0.3
m.shader.directColor=color(255)*0.7
m.shader.fog=5000
m.shader.mistColor=backgroundColor
m.shader.offset=0
return m
end
--# Main2
-- Tiger2
displayMode(FULLSCREEN)
function setup()
backgroundColor=color(129, 162, 201, 255)
T={}
for i=0,10 do
for j=1,10 do
local k=i*10+j
T[k]=Tank()
T[k].pos=vec3(350+j*25,0.5,-1000+i*50)
T[k].turretAngle=math.random(0,360)
T[k]:rotate(180)
end
end
Terrain=MakeTerrain(1000,1000,"Dropbox:3D-grass1",.05)
camPos=vec3(500,15,0)
ax,ay=0,0
da=0.1
FPS=60
end
function draw()
background(backgroundColor)
FPS=FPS*0.9+0.1/DeltaTime
perspective()
camera(camPos.x,camPos.y,camPos.z,500,0,-500)
Terrain.shader.camPos=camPos
Terrain:draw()
for _,t in pairs(T) do
t.turretAngle=t.turretAngle+0.5
--T.gunAngle=T.gunAngle-da
--if -T.gunAngle<T.turretMaxAngles[1] or -T.gunAngle>T.turretMaxAngles[2] then da=-da end
t:draw(camPos)
end
ortho()
viewMatrix(matrix())
fill(0)
fontSize(24)
text("FPS: "..math.floor(FPS),50,50)
end
function touched(t)
if t.state~=ENDED then
ay,ax=ay+t.deltaX,ax+t.deltaY
end
end
function SetLighting(m)
m.shader=shader(TankShader.v,TankShader.f)
m.shader.directDirection=vec4(-2,2,1,0):normalize()
m.shader.ambientColor=color(255)*0.5
m.shader.directColor=color(255)*0.5
m.shader.fog=5000
m.shader.mistColor=backgroundColor
m.shader.offset=0
return m
end
--# Test8
--[[
function setup()
local w,h,f=200,200,5
img1=image(w,h)
local c1=color(232, 223, 231, 255)
local c2=color(23, 23, 19, 255)
local mn,mx=999,0
for i=1,w do
for j=1,h do
local m=(noise(i/w*f,j/h*f)+1)/2
mn=math.min(m,mn) mx=math.max(m,mx)
img1:set(i,j,c1:mix(c2,m))
end
end
print(mn,mx)
eee=img1
end
function draw()
background(0)
sprite(img1,300,300)
end
--]]
--# Model2
--Model2
Tank=class()
Tank.turretMaxAngles=vec2(-5,20)
function Tank:init()
if not Tank.model then
Tank.LoadTextures()
Tank.CreateModel()
end
self.trackOffset=0
self.turretAngle=0
self.gunAngle=0
self.health=100
self.speed=0.25
self.angle=-90
self.rad=math.rad(self.angle)
self.pos=vec3(0,0,0)
end
function Tank:draw(camPos)
self.trackOffset=self.trackOffset-self.speed/1000
self.pos=self.pos+vec3(math.cos(self.rad),0,math.sin(self.rad))*self.speed
local m=Tank.model
m.track.shader.offset=self.trackOffset
pushMatrix()
translate(self.pos:unpack())
rotate(self.angle,0,1,0)
Tank.Wobble()
m.wheels.shader.mModel=modelMatrix() m.wheels.shader.camPos=camPos m.wheels:draw()
m.track.shader.mModel=modelMatrix() m.track.shader.camPos=camPos m.track:draw()
m.body.shader.mModel=modelMatrix() m.body.shader.camPos=camPos m.body:draw()
rotate(self.turretAngle,0,1,0)
m.turret.shader.mModel=modelMatrix() m.turret.shader.camPos=camPos m.turret:draw()
translate(-3.8,5.75,0)
rotate(self.gunAngle,0,0,1)
m.barrel.shader.mModel=modelMatrix() m.barrel.shader.camPos=camPos m.barrel:draw()
popMatrix()
end
function Tank:rotate(a)
self.angle=self.angle+a
self.rad=math.rad(self.angle)
end
function Tank.Wobble()
local f=.1
local a,b=ElapsedTime*f,ElapsedTime*math.pi*f
rotate(10*noise(a,b),1,0,0)
rotate(3*noise(b,a),0,0,1)
end
function Tank.LoadTextures()
Tank.texBody=readImage("Dropbox:Tank_Body")
if not Tank.texBody then
local w,h,f=200,200,5
local img1=image(w,h)
local c1=color(122, 184, 121, 255)
local c2=color(70, 122, 73, 255)
for i=1,w do
for j=1,h do
local m=(noise(i/w*f,j/h*f)+1)/2
img1:set(i,j,c1:mix(c2,m))
end
end
saveImage("Dropbox:Tank_Body",img1)
Tank.texBody=img1
end
--Track-------
Tank.texTrack=readImage("Dropbox:Tank_Track")
if not Tank.texTrack then
local img=image(50,5)
setContext(img)
pushStyle()
noSmooth()
background(123, 122, 122, 255)
stroke(25)
strokeWidth(0.5)
for i=1,img.width do
line(i,0,i,5)
end
popStyle()
setContext()
saveImage("Dropbox:Tank_Track",img)
Tank.texTrack=img
end
--Wheel-------
Tank.texWheel=readImage("Dropbox:Tank_Wheel")
if not Tank.texWheel then
img=image(100,10)
setContext(img)
background(0)
pushStyle()
noSmooth()
fill(99, 139, 85, 255)
stroke(51, 99, 50, 255)
strokeWidth(2)
for i=1,4 do
ellipse(i*26-11,10,20)
end
fill(80, 107, 84, 255)
for i=1,4 do
ellipse(i*26-11,10,4)
end
fill(99, 139, 85, 255)
for i=1,3 do
ellipse(2+i*26,9,20)
end
fill(80, 107, 84, 255)
for i=1,4 do
ellipse(2+i*26,9,4)
end
popStyle()
setContext()
saveImage("Dropbox:Tank_Wheel",img)
Tank.texWheel=img
end
end
function Tank.CreateModel()
local x1,x2,x3,y1,y2,y3,z1,z2,z3,z4,f1,f2
--body of tank
local body=mesh()
local v,t,c={},{},{}
x1,x2,y,z1,z2=-8.25,8.25,4.5,3.5,-3.5 --deck
v[#v+1]=vec3(x1,y,z1) v[#v+1]=vec3(x2,y,z1) v[#v+1]=vec3(x2,y,z2)
v[#v+1]=vec3(x2,y,z2) v[#v+1]=vec3(x1,y,z2) v[#v+1]=vec3(x1,y,z1)
x,y1,y2,z1,z2=8.25,2,4.5,3.5,-3.5 --back
v[#v+1]=vec3(x,y1,z1) v[#v+1]=vec3(x,y1,z2) v[#v+1]=vec3(x,y2,z2)
v[#v+1]=vec3(x,y2,z2) v[#v+1]=vec3(x,y2,z1) v[#v+1]=vec3(x,y1,z1)
x1,x2,y1,y2,z1,z2,z3,z4=-11,-8.25,3,4.5,-4.5,4.5,-3.5,3.5 --front #2 angle
v[#v+1]=vec3(x1,y1,z1) v[#v+1]=vec3(x1,y1,z2) v[#v+1]=vec3(x2,y2,z4)
v[#v+1]=vec3(x2,y2,z4) v[#v+1]=vec3(x2,y2,z3) v[#v+1]=vec3(x1,y1,z1)
x1,x2,y1,y2,y3,z1,z2=-8.25,8.25,2,2,3.5,4.5,-4.5 --sides
v[#v+1]=vec3(x1,y1,z1) v[#v+1]=vec3(x2,y2,z1) v[#v+1]=vec3(x2,y3,z1)
v[#v+1]=vec3(x2,y3,z1) v[#v+1]=vec3(x1,y3,z1) v[#v+1]=vec3(x1,y1,z1)
v[#v+1]=vec3(x2,y2,z2) v[#v+1]=vec3(x1,y1,z2) v[#v+1]=vec3(x1,y3,z2)
v[#v+1]=vec3(x1,y3,z2) v[#v+1]=vec3(x2,y3,z2) v[#v+1]=vec3(x2,y2,z2)
x1,x2,y1,y2,z1,z2=-8.25,8.25,3.5,4.5,4.5,3.5
v[#v+1]=vec3(x1,y1,z1) v[#v+1]=vec3(x2,y1,z1) v[#v+1]=vec3(x2,y2,z2)
v[#v+1]=vec3(x2,y2,z2) v[#v+1]=vec3(x1,y2,z2) v[#v+1]=vec3(x1,y1,z1)
x1,x2,y1,y2,z1,z2=8.25,-8.25,3.5,4.5,-4.5,-3.5
v[#v+1]=vec3(x1,y1,z1) v[#v+1]=vec3(x2,y1,z1) v[#v+1]=vec3(x2,y2,z2)
v[#v+1]=vec3(x2,y2,z2) v[#v+1]=vec3(x1,y2,z2) v[#v+1]=vec3(x1,y1,z1)
x1,x2,y1,z1,z2=-10,7.25,1,-2.5,2.5 --underneath
v[#v+1]=vec3(x1,y1,z1) v[#v+1]=vec3(x2,y1,z1) v[#v+1]=vec3(x2,y1,z2)
v[#v+1]=vec3(x2,y1,z2) v[#v+1]=vec3(x1,y1,z2) v[#v+1]=vec3(x1,y1,z1)
x,y1,y2,z1,z2=-11,2,3,-4.5,4.5 --front bottom
v[#v+1]=vec3(x,y1,z1) v[#v+1]=vec3(x,y1,z2) v[#v+1]=vec3(x,y2,z2)
v[#v+1]=vec3(x,y2,z2) v[#v+1]=vec3(x,y2,z1) v[#v+1]=vec3(x,y1,z1)
x1,x2,y1,y2,z1,z2=-10,-11,1,2,-2.5,2.5 --front under slant
v[#v+1]=vec3(x1,y1,z1) v[#v+1]=vec3(x1,y1,z2) v[#v+1]=vec3(x2,y2,z2)
v[#v+1]=vec3(x2,y2,z2) v[#v+1]=vec3(x2,y2,z1) v[#v+1]=vec3(x1,y1,z1)
x1,x2,y1,y2,z1,z2=7.25,8.25,1,2,2.5,-2.5 --back under slant
v[#v+1]=vec3(x1,y1,z1) v[#v+1]=vec3(x1,y1,z2) v[#v+1]=vec3(x2,y2,z2)
v[#v+1]=vec3(x2,y2,z2) v[#v+1]=vec3(x2,y2,z1) v[#v+1]=vec3(x1,y1,z1)
x1,x2,x3,y1,y2,y3,z1,z2=-11,-8.25,-8.25,3,2,3.5,4.5,3.5 --fill the cracks
v[#v+1]=vec3(x,y1,z1) v[#v+1]=vec3(x2,y2,z1) v[#v+1]=vec3(x3,y3,z1)
z1=-4.5
v[#v+1]=vec3(x,y1,z1) v[#v+1]=vec3(x3,y3,z1) v[#v+1]=vec3(x2,y2,z1)
x1,x2,x3,y1,y2,y3,z1=-11,-11,-8.25,3,2,2,4.5
v[#v+1]=vec3(x,y1,z1) v[#v+1]=vec3(x2,y2,z1) v[#v+1]=vec3(x3,y3,z1)
z1=-4.5
v[#v+1]=vec3(x,y1,z1) v[#v+1]=vec3(x3,y3,z1) v[#v+1]=vec3(x2,y2,z1)
x1,x2,y1,y2,y3,z1,z2=-11,-8.25,3,3.5,4.5,4.5,3.5
v[#v+1]=vec3(x1,y1,z1) v[#v+1]=vec3(x2,y2,z1) v[#v+1]=vec3(x2,y3,z2)
v[#v+1]=vec3(x1,y1,-z1) v[#v+1]=vec3(x2,y3,-z2) v[#v+1]=vec3(x2,y2,-z1)
x1,y1,y2,z1,z2=8.25,5.5,6.5,3.5,-3.5
x1,y1,y2,z1,z2=8.25,2,3.5,4.5,3.5
v[#v+1]=vec3(x1,y1,z1) v[#v+1]=vec3(x1,y1,z2) v[#v+1]=vec3(x1,y2,z2)
v[#v+1]=vec3(x1,y2,z2) v[#v+1]=vec3(x1,y2,z1) v[#v+1]=vec3(x1,y1,z1)
v[#v+1]=vec3(x1,y1,-z1) v[#v+1]=vec3(x1,y2,-z2) v[#v+1]=vec3(x1,y1,-z2)
v[#v+1]=vec3(x1,y2,-z2) v[#v+1]=vec3(x1,y1,-z1) v[#v+1]=vec3(x1,y2,-z1)
x1,y1,y2,z1,z2=8.25,3.5,4.5,4.5,3.5
v[#v+1]=vec3(x1,y1,z1) v[#v+1]=vec3(x1,y1,z2) v[#v+1]=vec3(x1,y2,z2)
z1,z2=-3.5,-4.5
v[#v+1]=vec3(x1,y1,z1) v[#v+1]=vec3(x1,y1,z2) v[#v+1]=vec3(x1,y2,z1)
body.vertices=v
body:setColors(color(90))
body.texture=Tank.texBody
body.name="body"
--tracks
local track,v,t=mesh(),{},{}
local f=.05
x1,x2,y1,y2,z1,z2,f1,f2=8.25,8.25,1,2,4.5,2.5,0,f*2 --back right vert
v[#v+1]=vec3(x1,y1,z1) v[#v+1]=vec3(x1,y1,z2) v[#v+1]=vec3(x2,y2,z2)
v[#v+1]=vec3(x2,y2,z2) v[#v+1]=vec3(x2,y2,z1) v[#v+1]=vec3(x1,y1,z1)
t[#t+1]=vec2(f1,0) t[#t+1]=vec2(f1,1) t[#t+1]=vec2(f2,1)
t[#t+1]=vec2(f2,1) t[#t+1]=vec2(f2,0) t[#t+1]=vec2(f1,0)
z1,z2=-2.5,-4.5 --back left vert
v[#v+1]=vec3(x1,y1,z1) v[#v+1]=vec3(x1,y1,z2) v[#v+1]=vec3(x2,y2,z2)
v[#v+1]=vec3(x2,y2,z2) v[#v+1]=vec3(x2,y2,z1) v[#v+1]=vec3(x1,y1,z1)
t[#t+1]=vec2(f1,0) t[#t+1]=vec2(f1,1) t[#t+1]=vec2(f2,1)
t[#t+1]=vec2(f2,1) t[#t+1]=vec2(f2,0) t[#t+1]=vec2(f1,0)
x1,x2,y1,y2,z1,z2,f1,f2=7.25,8.25,0,1,4.5,2.5,f*2,f*4 --back right slant
v[#v+1]=vec3(x1,y1,z1) v[#v+1]=vec3(x1,y1,z2) v[#v+1]=vec3(x2,y2,z2)
v[#v+1]=vec3(x2,y2,z2) v[#v+1]=vec3(x2,y2,z1) v[#v+1]=vec3(x1,y1,z1)
t[#t+1]=vec2(f1,0) t[#t+1]=vec2(f1,1) t[#t+1]=vec2(f2,1)
t[#t+1]=vec2(f2,1) t[#t+1]=vec2(f2,0) t[#t+1]=vec2(f1,0)
z1,z2=-2.5,-4.5 --back left slant
v[#v+1]=vec3(x1,y1,z1) v[#v+1]=vec3(x1,y1,z2) v[#v+1]=vec3(x2,y2,z2)
v[#v+1]=vec3(x2,y2,z2) v[#v+1]=vec3(x2,y2,z1) v[#v+1]=vec3(x1,y1,z1)
t[#t+1]=vec2(f1,0) t[#t+1]=vec2(f1,1) t[#t+1]=vec2(f2,1)
t[#t+1]=vec2(f2,1) t[#t+1]=vec2(f2,0) t[#t+1]=vec2(f1,0)
x1,x2,y1,y2,z1,z2,f1,f2=-9,-11,0,2,2.5,4.5,0,f*2 --front right slant
v[#v+1]=vec3(x1,y1,z1) v[#v+1]=vec3(x1,y1,z2) v[#v+1]=vec3(x2,y2,z2)
v[#v+1]=vec3(x2,y2,z2) v[#v+1]=vec3(x2,y2,z1) v[#v+1]=vec3(x1,y1,z1)
t[#t+1]=vec2(f2,0) t[#t+1]=vec2(f2,1) t[#t+1]=vec2(f1,1)
t[#t+1]=vec2(f1,1) t[#t+1]=vec2(f1,0) t[#t+1]=vec2(f2,0)
z1,z2=-4.5,-2.5 --front left slant
v[#v+1]=vec3(x1,y1,z1) v[#v+1]=vec3(x1,y1,z2) v[#v+1]=vec3(x2,y2,z2)
v[#v+1]=vec3(x2,y2,z2) v[#v+1]=vec3(x2,y2,z1) v[#v+1]=vec3(x1,y1,z1)
t[#t+1]=vec2(f2,0) t[#t+1]=vec2(f2,1) t[#t+1]=vec2(f1,1)
t[#t+1]=vec2(f1,1) t[#t+1]=vec2(f1,0) t[#t+1]=vec2(f2,0)
x1,x2,y1,y2,z1,z2,f1,f2=-9,7.25,0,0,4.5,2.5,4*f,20.25*f --bottom right track
v[#v+1]=vec3(x1,y1,z1) v[#v+1]=vec3(x1,y1,z2) v[#v+1]=vec3(x2,y1,z2)
v[#v+1]=vec3(x2,y1,z2) v[#v+1]=vec3(x2,y1,z1) v[#v+1]=vec3(x1,y1,z1)
t[#t+1]=vec2(f1,0) t[#t+1]=vec2(f1,1) t[#t+1]=vec2(f2,1)
t[#t+1]=vec2(f2,1) t[#t+1]=vec2(f2,0) t[#t+1]=vec2(f1,0)
z1,z2=-2.5,-4.5 --bottom left track
v[#v+1]=vec3(x1,y1,z1) v[#v+1]=vec3(x1,y1,z2) v[#v+1]=vec3(x2,y1,z2)
v[#v+1]=vec3(x2,y1,z2) v[#v+1]=vec3(x2,y1,z1) v[#v+1]=vec3(x1,y1,z1)
t[#t+1]=vec2(f1,0) t[#t+1]=vec2(f1,1) t[#t+1]=vec2(f2,1)
t[#t+1]=vec2(f2,1) t[#t+1]=vec2(f2,0) t[#t+1]=vec2(f1,0)
track.vertices=v
track.texCoords=t
track:setColors(color(40))
track.texture=Tank.texTrack
track.name="track"
wheels,v,t=mesh(),{},{}
x1,x2,y1,y2,z1=-11,-9,2,0,4
v[#v+1]=vec3(x1,y1,z1) v[#v+1]=vec3(x2,y2,z1) v[#v+1]=vec3(x2,y1,z1)
x1,x2,y1,y2,z1=-9,7.25,2,0,4
v[#v+1]=vec3(x1,y2,z1) v[#v+1]=vec3(x2,y2,z1) v[#v+1]=vec3(x2,y1,z1)
v[#v+1]=vec3(x2,y1,z1) v[#v+1]=vec3(x1,y1,z1) v[#v+1]=vec3(x1,y2,z1)
x1,x2,y1,y2,y3,z1=7.25,8.25,0,1,2,4
v[#v+1]=vec3(x1,y1,z1) v[#v+1]=vec3(x2,y2,z1) v[#v+1]=vec3(x1,y3,z1)
v[#v+1]=vec3(x2,y2,z1) v[#v+1]=vec3(x2,y3,z1) v[#v+1]=vec3(x1,y3,z1)
x1,x2,y1,y2,z1=-11,-9,2,0,-4
v[#v+1]=vec3(x1,y1,z1) v[#v+1]=vec3(x2,y1,z1) v[#v+1]=vec3(x2,y2,z1)
x1,x2,y1,y2,z1=-9,7.25,2,0,-4
v[#v+1]=vec3(x2,y2,z1) v[#v+1]=vec3(x1,y2,z1) v[#v+1]=vec3(x1,y1,z1)
v[#v+1]=vec3(x1,y1,z1) v[#v+1]=vec3(x2,y1,z1) v[#v+1]=vec3(x2,y2,z1)
x1,x2,y1,y2,y3,z1=7.25,8.25,0,1,2,-4
v[#v+1]=vec3(x1,y1,z1) v[#v+1]=vec3(x1,y3,z1) v[#v+1]=vec3(x2,y2,z1)
v[#v+1]=vec3(x2,y2,z1) v[#v+1]=vec3(x1,y3,z1) v[#v+1]=vec3(x2,y3,z1)
for i=1,#v/2 do t[#t+1]=vec2((v[i].x+11)/19,v[i].y/2) end
for i=#v/2+1,#v do t[#t+1]=vec2(-(8.25-v[i].x)/19,v[i].y/2) end
wheels.vertices=v
wheels.texCoords=t
wheels:setColors(color(255,0,0))
wheels.texture=Tank.texWheel
wheels.name="wheels"
local turret,v=mesh(),{}
local h,y,slope=2.5,4.5,0.5
local p={vec3(-4,0,1.5),vec3(0,0,3.5),vec3(2,0,3),vec3(4,0,1),vec3(4,0,-1),
vec3(2,0,-3),vec3(0,0,-3.5),vec3(-4,0,-1.5)}
for i=1,#p do p[i].y=y+(p[i].x/8+0.5)*slope end
for i=1,#p do
local a,b=p[i],p[i+1] or p[1]
v[#v+1]=vec3(a.x,y,a.z)
v[#v+1]=vec3(b.x,y,b.z)
v[#v+1]=vec3(b.x,b.y+h,b.z)
v[#v+1]=vec3(b.x,b.y+h,b.z)
v[#v+1]=vec3(a.x,a.y+h,a.z)
v[#v+1]=vec3(a.x,y,a.z)
end
local norm={}
for i=1,#v do norm[i]=v[i]:normalize() end
--roof
for i=1,#p do
local a,b=p[i],p[i+1] or p[1]
v[#v+1]=vec3(a.x,a.y+h,a.z)
v[#v+1]=vec3(b.x,b.y+h,b.z)
v[#v+1]=vec3(0,y+h+slope/2,0)
for j=1,3 do norm[#norm+1]=vec3(0,1,0) end
end
turret.vertices=v
turret.normals=norm
turret:setColors(color(90))
turret.texture=Tank.texBody
turret.name="turret"
barrel,p,v,norm=mesh(),{},{},{}
local x1,x2,r1,r2,y=-4,-7,0.75,0.4,7.75
for i=1,8 do p[i]=vec3(0,math.cos(i*math.pi/4),math.sin(i*math.pi/4)) end
for i=1,8 do
local p1,p2=p[i],p[i+1] or p[1]
v[#v+1]=vec3(x1,y+p1.y*r1,p1.z*r1)
v[#v+1]=vec3(x2,y+p1.y*r2,p1.z*r2)
v[#v+1]=vec3(x2,y+p2.y*r2,p2.z*r2)
v[#v+1]=vec3(x2,y+p2.y*r2,p2.z*r2)
v[#v+1]=vec3(x1,y+p2.y*r1,p2.z*r1)
v[#v+1]=vec3(x1,y+p1.y*r1,p1.z*r1)
end
local x1,x2,r1,r2,y=-7,-17,0.4,0.3,7.75
for i=1,8 do p[i]=vec3(0,math.cos(i*math.pi/4),math.sin(i*math.pi/4)) end
for i=1,8 do
local p1,p2=p[i],p[i+1] or p[1]
v[#v+1]=vec3(x1,y+p1.y*r1,p1.z*r1)
v[#v+1]=vec3(x2,y+p1.y*r2,p1.z*r2)
v[#v+1]=vec3(x2,y+p2.y*r2,p2.z*r2)
v[#v+1]=vec3(x2,y+p2.y*r2,p2.z*r2)
v[#v+1]=vec3(x1,y+p2.y*r1,p2.z*r1)
v[#v+1]=vec3(x1,y+p1.y*r1,p1.z*r1)
end
for i=1,#v do norm[i]=(v[i]-vec3(v[i].x,y,0)):normalize() end
for i=1,#v do v[i].x,v[i].y=v[i].x+4,v[i].y-7.75 end
barrel.vertices=v
barrel.normals=norm
barrel:setColors(color(90))
barrel.texture=Tank.texBody
barrel.name="barrel"
print("vertices=",body.size+track.size+turret.size+barrel.size+wheels.size)
local tank={body=body,track=track,turret=turret,barrel=barrel,wheels=wheels}
for _,m in pairs(tank) do
local norm={}
local nn=m:buffer("normal")
if nn[1]==nil then
local v=m:buffer("position")
for i=1,m.size,3 do
local v1,v2=v[i]-v[i+2],v[i+1]-v[i+2]
local n=(v1:cross(v2)):normalize()
norm[i],norm[i+1],norm[i+2]=n,n,n
end
m.normals=norm
end
if m.texture==Tank.texBody then
local t={}
local v=m:buffer("position")
for i=1,m.size do
t[i]=vec2(v[i].x/8+v[i].z/5,v[i].y/6+v[i].z/5)/2
end
m.texCoords=t
end
m=SetLighting(m)
end
Tank.model=tank
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment