http://spring.clan-sy.com/phpbb/viewtop ... 7&start=20
seem to be quietly working on new animation/model systems, I felt like trying someting too and wanted to make a LUA script for .md5. I have so far managed to draw the contents of an .md5mesh in a basic way (no normals, etc). Unfortunately however, the performance so far really sucks.

This is some crappy .md5 model I found on the internet with apparantly 4372 triangles. This would be the equivalent of about 20 guys with a more reasonable 200polygons for example. Sadly this makes fps go down to around 18. Looking closely at the model, it's really bad, it doesn't even make use of skeletal animation the way it's setup, with one mesh per bone. I couldn't find any of the doom3 models around, might install it to get at them later.
It's probably handling all the weights that slows it down the most, requireing a quaternion rotation (25 multiplications + 25 additions) and all the function calls between the thousands of weights, vertices etc.
I was hoping to maybe unload processing into the vertice shader to circumvent LUA:s disadvantages, but I think one would need to use a geametry shader (nvidia8800+) for this to be feasible. In the end it's probably necessary to go with engine side code to be practical, but I have never felt like going trough with the troubles of setting up the ability to compile the spring source code and then getting intimate enough to work with it.
Anyway it's still useful to me as an experiment to learn stuff, see what can be done etc so I will probably continue a bit more.
Here's the code sofar:
Code: Select all
function widget:GetInfo()
  return {
    name      = "boneanim",
    desc      = "Skeletal animation",
    author    = "zpock",
    date      = "July 28, 2008",
    license   = "GPL",
    layer     = 0,
    enabled   = true  --  loaded by default?
  }
end
local shieldshader
local joints = {}
local meshes = {}
function widget:Initialize()
    io.input("cubby3.md5mesh")
	local total = io.read("*all")
	
	_,_,skel = string.find(total, "joints %{(.-)%}")
	
	local i ,j, t = 0, 0, -1 
	while true do
		i, j, nr = string.find(skel, '(".-".-)\n', j+1)
		if i == nil then break end
		
		t = t+1
		local _,_,name = string.find(nr, '"(.-)"')
		local _,_,parent = string.find(nr, '".-" (.-) ')
		local _,_,x = string.find(nr, '%( (.-) ')
		local _,_,y = string.find(nr, '%( .- (.-) ')
		local _,_,z = string.find(nr, '%( .- .- (.-) ')
		local _,_,xo = string.find(nr, '%(.-%) %( (.-) ')
		local _,_,yo = string.find(nr, '%(.-%) %( .- (.-) ')
		local _,_,zo = string.find(nr, '%(.-%) %( .- .- (.-) ')
		
		local joint = {}
		joint.name = name
		joint.parent = tonumber(parent)
		joint.x = tonumber(x)
		joint.y = tonumber(y)
		joint.z = tonumber(z)
		joint.xo = tonumber(xo)
		joint.yo = tonumber(yo)
		joint.zo = tonumber(zo)
		
		local kuk = 1 - xo^2 - yo^2 - zo^2
		if kuk < 0 then
			joint.wo = 0
		else
			joint.wo = -math.sqrt(kuk)
		end
		
		joints[t] = joint	
 	end
	 
	local i2, j2, t2 = 0,0,0
	while true do
		i2,j2,s = string.find(total, "mesh %{(.-)%}", j2+1)
		if i2 == nil then break end
		
		local verts = {}
		local tris = {}
		local weights = {}
		
	
	
	i ,j = 0, 0
	while true do
		i, j, nr = string.find(s, "vert (.-)\n", i+1)
		if i == nil then break end
		
		local _,_,t = string.find(nr, "(%d+)")
		local _,_,u = string.find(nr, "%( (.-) ")
		local _,_,v = string.find(nr, "%( .- (.-) ")
		local _,_,start = string.find(nr, "%) (%d+)")
		local _,_,count = string.find(nr, "%) %d+ (%d+)")
		
		local vert = {}
		vert.u = tonumber(u)
		vert.v = tonumber(v)
		vert.start = tonumber(start)
		vert.count = tonumber(count)
		
		verts[tonumber(t)] = vert
		
 	end
	 
	i ,j = 0, 0
	while true do
		i, j, nr = string.find(s, "tri (.-)\n", i+1)
		if i == nil then break end
		
		local _,_,t = string.find(nr, "(%d+)")
		local _,_,v1 = string.find(nr, "%d+ (%d+)")
		local _,_,v2 = string.find(nr, "%d+ %d+ (%d+)")
		local _,_,v3 = string.find(nr, "%d+ %d+ %d+ (%d+)")
		
		local tri = {}
		tri[1] = tonumber(v1)
		tri[2] = tonumber(v2)
		tri[3] = tonumber(v3)
		
		tris[tonumber(t)] = tri	
 	end
	
	i ,j = 0, 0 
	while true do
		i, j, nr = string.find(s, "weight (.-)\n", i+1)
		if i == nil then break end
		
		local _,_,t = string.find(nr, "(%d+)")
		local _,_,joint = string.find(nr, "%d+ (%d+)")
		local _,_,bias = string.find(nr, "%d+ %d+ (.-) ")
		local _,_,x = string.find(nr, "%( (.-) ")
		local _,_,y = string.find(nr, "%( .- (.-) ")
		local _,_,z = string.find(nr, "%( .- .- (.-) ")
		
		local weight = {}
		weight.joint = tonumber(joint)
		weight.bias = tonumber(bias)
		weight.x = tonumber(x)
		weight.y = tonumber(y)
		weight.z = tonumber(z)
		
		weights[tonumber(t)] = weight	
 	end
	
	meshes[t2] = {} 
	meshes[t2].verts = verts
	meshes[t2].tris = tris
	meshes[t2].weights = weights
	
	t2 = t2+1 
	 
	end  
end
function widget:GameFrame(n)
	
end
function qmult(qax,qay,qaz,qaw,qbx,qby,qbz,qbw)
	local rw = (qaw * qbw) - (qax * qbx) - (qay * qby) - (qaz * qbz)
	local rx = (qax * qbw) + (qaw * qbx) + (qay * qbz) - (qaz * qby)
	local ry = (qay * qbw) + (qaw * qby) + (qaz * qbx) - (qax * qbz)
	local rz = (qaz * qbw) + (qaw * qbz) + (qax * qby) - (qay * qbx)
	return rx, ry, rz, rw
end
function qrot(qax,qay,qaz,qaw,qbx,qby,qbz,qbw)
	rx, ry, rz, rw = qmult(qax,qay,qaz,qaw,qbx,qby,qbz,qbw)
	rx, ry, rz, rw = qmult(rx,ry,rz,rw,-qax,-qay,-qaz,qaw)
	return rx, ry, rz
end
function widget:DrawWorld()
	local numtris = 0
	for key2, value2 in pairs(meshes) do
	for key, value in pairs(value2.weights) do
		
		value.xp, value.yp, value.zp = qrot(joints[value.joint].xo, joints[value.joint].yo, joints[value.joint].zo, joints[value.joint].wo, value.x, value.y, value.z, 0)
	
		value.xp = value.xp + joints[value.joint].x
		value.yp = value.yp + joints[value.joint].y
		value.zp = value.zp + joints[value.joint].z	
	end
	
	for key, value in pairs(value2.verts) do
		value.xp,value.yp,value.zp = 0,0,0
	
		for i = 0, value.count - 1 do
			local bias = value2.weights[value.start + i].bias
			value.xp = value.xp + value2.weights[value.start + i].xp*bias
			value.yp = value.yp + value2.weights[value.start + i].yp*bias
			value.zp = value.zp + value2.weights[value.start + i].zp*bias
		end		
	end
	
	gl.DepthTest(true)
  	gl.DepthMask(true)
    gl.PushMatrix()
  	gl.Translate(100, 100, 100)
  	
	gl.Texture('mupp/pCube1_joint1 copy.jpg')
	
	for key, value in pairs(value2.tris) do
		gl.BeginEnd(GL.TRIANGLES, function()
    	gl.TexCoord(0,0)
		gl.Vertex(value2.verts[value[1]].xp,value2.verts[value[1]].yp,value2.verts[value[1]].zp)
	   	gl.TexCoord(1,0)
		gl.Vertex(value2.verts[value[2]].xp,value2.verts[value[2]].yp,value2.verts[value[2]].zp)
	   	gl.TexCoord(1,1)
		gl.Vertex(value2.verts[value[3]].xp,value2.verts[value[3]].yp,value2.verts[value[3]].zp)
		end)
		numtris = numtris + 1			
	end
  		
  	gl.PopMatrix();
  	end
  	
  	Spring.Echo(numtris)
	
end









