Last active
January 8, 2021 01:54
-
-
Save sp4cemonkey/5728758 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
--# Main | |
-- Skeletal Animation | |
--helper function for matrix vector maths | |
function matrixByVector(m, v) | |
m=m:transpose() | |
vx = vec4(m[1], m[2], m[3], m[4]):dot(v) | |
vy = vec4(m[5], m[6], m[7], m[8]):dot(v) | |
vz = vec4(m[9], m[10], m[11], m[12]):dot(v) | |
vw = vec4(m[13], m[14], m[15], m[16]):dot(v) | |
return vec4(vx, vy, vz, vw) | |
-- return vec4(vx/vw, vy/vw, vz/vw) | |
end | |
-- Use this function to perform your initial setup | |
function setup() | |
figure = mesh() | |
verts = {} | |
boneWeights = {} --vec4 x bone1, y weight1, z bone2, w weight2 | |
tv = Primitive:Sphere(2) | |
--Create a mesh and boneweights for each vertex | |
--for now it's a mesh that looks like the skeleton, but in the future could be | |
--any mesh, and boneweights can be derived automatically but currently hard coded | |
--left foot | |
m = matrix() | |
m = m:translate(-1,0.25,0) | |
m = m:scale(0.5) | |
for k,v in ipairs(tv) do | |
lv = matrixByVector(m, vec4(v.x,v.y,v.z,1.0)) | |
table.insert(boneWeights, vec4(4,1,0,0)) | |
table.insert(verts, lv) | |
end | |
--right foot | |
m = matrix() | |
m = m:translate(1,0.25,0) | |
m = m:scale(0.5) | |
for k,v in ipairs(tv) do | |
lv = matrixByVector(m, vec4(v.x,v.y,v.z,1.0)) | |
table.insert(boneWeights, vec4(7,1,0,0)) | |
table.insert(verts, lv) | |
end | |
m = matrix() | |
m = m:translate(-3,5,0) | |
m = m:scale(0.5) | |
--left hand | |
for k,v in ipairs(tv) do | |
lv = matrixByVector(m, vec4(v.x,v.y,v.z,1.0)) | |
table.insert(boneWeights, vec4(11,1,0,0)) | |
table.insert(verts, lv) | |
end | |
m = matrix() | |
m = m:translate(3,5,0) | |
m = m:scale(0.5) | |
--right hand | |
for k,v in ipairs(tv) do | |
lv = matrixByVector(m, vec4(v.x,v.y,v.z,1.0)) | |
table.insert(boneWeights, vec4(14,1,0,0)) | |
table.insert(verts, lv) | |
end | |
--head | |
m = matrix() | |
m = m:translate(0,6.5,0) | |
for k,v in ipairs(tv) do | |
lv = matrixByVector(m, vec4(v.x,v.y,v.z,1.0)) | |
table.insert(boneWeights, vec4(15,1,0,0)) | |
table.insert(verts, lv) | |
end | |
tv = Primitive:Cube(1) | |
--left lower leg | |
m = matrix() | |
m = m:translate(-0.8,1,0) | |
m = m:rotate(-15,0,0,1) | |
m = m:scale(0.5,1.5,0.5) | |
for k,v in ipairs(tv) do | |
lv = matrixByVector(m, vec4(v.x,v.y,v.z,1.0)) | |
--print(lv) | |
if lv.y < 1 then | |
table.insert(boneWeights, vec4(3,1,0,0)) | |
else | |
table.insert(boneWeights, vec4(3,0.7,2,0.3)) | |
end | |
--table.insert(boneWeights, vec4(3,1,0,0)) | |
table.insert(verts, lv) | |
end | |
--right lower leg | |
m = matrix() | |
m = m:translate(0.8,1,0) | |
m = m:rotate(15,0,0,1) | |
m = m:scale(0.5,1.5,0.5) | |
for k,v in ipairs(tv) do | |
lv = matrixByVector(m, vec4(v.x,v.y,v.z,1.0)) | |
table.insert(boneWeights, vec4(6,1,0,0)) | |
table.insert(verts, lv) | |
end | |
--left upper leg | |
m = matrix() | |
m = m:translate(-0.43,2.3,0) | |
m = m:rotate(-15,0,0,1) | |
m = m:scale(0.5,1.5,0.5) | |
print(#verts) | |
for k,v in ipairs(tv) do | |
lv = matrixByVector(m, vec4(v.x,v.y,v.z,1.0)) | |
--print(lv) | |
if lv.y > 2 then | |
table.insert(boneWeights, vec4(2,1,0,0)) | |
else | |
table.insert(boneWeights, vec4(2,0.7,3,0.3)) | |
end | |
table.insert(verts, lv) | |
end | |
print(#verts) | |
--right upper leg | |
m = matrix() | |
m = m:translate(0.43,2.3,0) | |
m = m:rotate(15,0,0,1) | |
m = m:scale(0.5,1.5,0.5) | |
for k,v in ipairs(tv) do | |
lv = matrixByVector(m, vec4(v.x,v.y,v.z,1.0)) | |
table.insert(boneWeights, vec4(5,1,0,0)) | |
table.insert(verts, lv) | |
end | |
--body | |
m = matrix() | |
m = m:translate(0,4,0) | |
m = m:scale(0.9,2.5,0.6) | |
for k,v in ipairs(tv) do | |
lv = matrixByVector(m, vec4(v.x,v.y,v.z,1.0)) | |
table.insert(boneWeights, vec4(1,1,0,0)) | |
table.insert(verts, lv) | |
end | |
--neck | |
m = matrix() | |
m = m:translate(0,5.5,0) | |
m = m:scale(0.5,1,0.5) | |
for k,v in ipairs(tv) do | |
lv = matrixByVector(m, vec4(v.x,v.y,v.z,1.0)) | |
table.insert(boneWeights, vec4(8,1,0,0)) | |
table.insert(verts, lv) | |
end | |
--left lower arm | |
m = matrix() | |
m = m:translate(-2.1,5,0) | |
m = m:scale(1.2,0.5,0.5) | |
for k,v in ipairs(tv) do | |
lv = matrixByVector(m, vec4(v.x,v.y,v.z,1.0)) | |
table.insert(boneWeights, vec4(10,1,0,0)) | |
table.insert(verts, lv) | |
end | |
--right lower arm | |
m = matrix() | |
m = m:translate(2.1,5,0) | |
m = m:scale(1.2,0.5,0.5) | |
for k,v in ipairs(tv) do | |
lv = matrixByVector(m, vec4(v.x,v.y,v.z,1.0)) | |
table.insert(boneWeights, vec4(13,1,0,0)) | |
table.insert(verts, lv) | |
end | |
--left upper arm | |
m = matrix() | |
m = m:translate(-1,5,0) | |
m = m:scale(1.2,0.5,0.5) | |
for k,v in ipairs(tv) do | |
lv = matrixByVector(m, vec4(v.x,v.y,v.z,1.0)) | |
table.insert(boneWeights, vec4(9,1,0,0)) | |
table.insert(verts, lv) | |
end | |
--right upper arm | |
m = matrix() | |
m = m:translate(1,5,0) | |
m = m:scale(1.2,0.5,0.5) | |
for k,v in ipairs(tv) do | |
lv = matrixByVector(m, vec4(v.x,v.y,v.z,1.0)) | |
table.insert(boneWeights, vec4(12,1,0,0)) | |
table.insert(verts, lv) | |
end | |
--Generate a skeleton using the bonetree class applying the translation to position bones relative to each other | |
m = matrix() | |
m = m:translate(0,3,0) | |
skeleton = BoneTree(m, "centre") | |
--left leg | |
m = matrix() | |
h = skeleton:addChild(m, "leftHip") | |
m = matrix() | |
m = m:translate(-0.6, -1.25, 0) | |
t = h:addChild(m, "leftKnee") | |
m = matrix() | |
m = m:translate(-0.3, -1, 0) | |
t:addChild(m, "leftFoot") | |
--right leg | |
m = matrix() | |
h = skeleton:addChild(m, "rightHip") | |
m = matrix() | |
m = m:translate(0.6, -1.25, 0) | |
t = h:addChild(m, "rightKnee") | |
m = matrix() | |
m = m:translate(0.3, -1, 0) | |
t:addChild(m, "rightFoot") | |
--body | |
m = matrix() | |
m = m:translate(0, 2.05, 0) | |
s = skeleton:addChild(m, "shoulders") | |
--left arm | |
m = matrix() | |
m = m:translate(-.3,0,0) | |
sj = s:addChild(m, "leftShoulder") | |
m = matrix() | |
m = m:translate(-1.2,0,0) | |
t = sj:addChild(m, "leftElbow") | |
m = matrix() | |
m = m:translate(-1,0,0) | |
t:addChild(m, "leftHand") | |
--right arm | |
m = matrix() | |
m = m:translate(.3,0,0) | |
sj = s:addChild(m, "rightShoulder") | |
m = matrix() | |
m = m:translate(1.2,0,0) | |
t = sj:addChild(m, "rightElbow") | |
m = matrix() | |
m = m:translate(1,0,0) | |
t:addChild(m, "rightHand") | |
--head | |
m = matrix() | |
m = m:translate(0,1,0) | |
s:addChild(m, "head") | |
--print a debug of the skeleton tree | |
skeleton:traverse("") | |
--put all my stuff into an actual Codea mesh | |
figure.shader = shader(boneShader.vertexShader, boneShader.fragmentShader) | |
figure.vertices = verts | |
--boneweights are a vertex attrbiute, so we have to process them into the buffer | |
boneWeightBuffer = figure:buffer("boneWeight") | |
boneWeightBuffer:resize(figure.size) | |
for k,v in ipairs(boneWeights) do | |
boneWeightBuffer[k] = v | |
end | |
figure:setColors(color(0,255,255,100)) | |
campos = vec2(0,-20) | |
--a marker mesh for debug | |
marker = mesh() | |
marker.vertices = Primitive:Cube(0.2) | |
marker:setColors(color(255,0,0,255)) | |
r = 50 | |
ri = 1 | |
rig = {} | |
rig.leftHip = {r = 0, j = skeleton:retrieveByTag("leftHip"), a = vec3(1,0,0)} | |
rig.leftKnee = { r = 0, j = skeleton:retrieveByTag("leftKnee"), a = vec3(1,0,0)} | |
rig.rightHip = {r = 0, j = skeleton:retrieveByTag("rightHip"), a = vec3(1,0,0)} | |
rig.rightKnee = {r = 0, j = skeleton:retrieveByTag("rightKnee"), a = vec3(1,0,0)} | |
rig.shoulders = {r = 0, j = skeleton:retrieveByTag("shoulders"), a = vec3(0,1,0)} | |
rig.rightShoulder = {r1 = 0, r2 = 0, j = skeleton:retrieveByTag("rightShoulder"), a1 = vec3(0,0,1), a2 = vec3(0,1,0)} | |
rig.leftShoulder = {r1 = 0, r2 = 0, j = skeleton:retrieveByTag("leftShoulder"), a1 = vec3(0,0,1), a2 = vec3(0,1,0)} | |
rig.rightElbow = {r = 0, j = skeleton:retrieveByTag("rightElbow"), a = vec3(0,1,0)} | |
rig.leftElbow = {r = 0, j = skeleton:retrieveByTag("leftElbow"), a = vec3(0,1,0)} | |
print(rig.rightHip) | |
walk(0.5) | |
end | |
function touched(touch) | |
if touch.state == MOVING then | |
campos = campos:rotate(math.rad(touch.deltaX/5)) | |
end | |
end | |
-- This function gets called once every frame | |
function draw() | |
--output.clear() | |
--print(1/DeltaTime) | |
--counter for arbitrary movement | |
r=r+ri | |
if r == 100 then | |
ri = -1 | |
end | |
if r == 0 then | |
ri = 1 | |
end | |
-- This sets a dark background color | |
background(0, 0, 0) | |
camera(campos.x,5,campos.y,0,4,0) | |
perspective() | |
--load some skeleton nodes and transform them for movement | |
-- x = skeleton:retrieveByTag("leftHip") | |
for k,v in pairs(rig) do | |
if v.r ~= nil then | |
m = matrix():rotate(v.r,v.a.x,v.a.y,v.a.z) | |
else | |
m = matrix():rotate(v.r1,v.a1.x,v.a1.y,v.a1.z):rotate(v.r2,v.a2.x,v.a2.y,v.a2.z) | |
end | |
v.j:applyTransform(m) | |
end | |
--pull out our bones and process them to the shader | |
t = {} | |
skeleton:retrieveBones(t) | |
i = 1 | |
for k,v in ipairs(t) do | |
loadstring("figure.shader.bones"..i.." = t["..i.."]")() | |
i=i+1 | |
end | |
t={} | |
skeleton:retrieveDebugBones(t) | |
for k,v in ipairs(t) do | |
--debug draw bone ends | |
modelMatrix(v) | |
marker:draw() | |
resetMatrix() | |
end | |
--draw the figure | |
resetMatrix() | |
figure:draw() | |
end | |
function walk(speed) | |
local h1 = tween( 2.0 * speed, rig.leftHip, { r = -30}, l) | |
local k1 = tween( 1.25 * speed, rig.leftKnee, { r = 45}, l) | |
local k2 = tween( 0.75 * speed, rig.leftKnee, { r = 0}, l) | |
local k3 = tween( 2.0 * speed, rig.leftKnee, { r = 0}, l) | |
local h2 = tween( 2.0 * speed, rig.leftHip, { r = 30}, l, function() walk(speed) end) | |
tween.sequence( h1,h2) | |
tween.sequence( k1,k2,k3) | |
local h1 = tween( 2.0 * speed, rig.rightHip, { r = 30}, l) | |
local k1 = tween( 2.0 * speed, rig.rightKnee, { r = 0}, l) | |
local k2 = tween( 1.25 * speed, rig.rightKnee, { r = 45}, l) | |
local k3 = tween( 0.75 * speed, rig.rightKnee, { r = 0}, l) | |
local h2 = tween( 2.0 * speed, rig.rightHip, { r = -30}, l) | |
tween.sequence( h1,h2) | |
tween.sequence( k1,k2,k3) | |
local s1 = tween( 2.0 * speed, rig.shoulders, {r = -10}, l) | |
local s2 = tween( 2.0 * speed, rig.shoulders, {r = 10}, l) | |
tween.sequence(s1,s2) | |
tween( 1.0 * speed, rig.rightShoulder, {r1 = -60}, l) | |
local rs1 = tween( 2.0 * speed, rig.rightShoulder, {r2 = -30}, l) | |
local rs2 = tween( 2.0 * speed, rig.rightShoulder, {r2 = 30}, l) | |
tween.sequence(rs1,rs2) | |
tween( 1.0 * speed, rig.leftShoulder, {r1 = 60}, l) | |
local rs1 = tween( 2.0 * speed, rig.leftShoulder, {r2 = -30}, l) | |
local rs2 = tween( 2.0 * speed, rig.leftShoulder, {r2 = 30}, l) | |
tween.sequence(rs1,rs2) | |
local e1 = tween( 2.0 * speed, rig.rightElbow, {r = -40}, l) | |
local e2 = tween( 2.0 * speed, rig.rightElbow, {r = 0}, l) | |
tween.sequence(e1,e2) | |
local e1 = tween( 2.0 * speed, rig.leftElbow, {r = 0}, l) | |
local e2 = tween( 2.0 * speed, rig.leftElbow, {r = 40}, l) | |
tween.sequence(e1,e2) | |
end | |
--# Primitive | |
Primitive = class() | |
--primitves gives basic mesh building for cubes and isospheres | |
--triangles are wound consistently to avoid gl_facing issues | |
function Primitive:Cube(s) | |
local vertices = { | |
vec3(-0.5*s, -0.5*s, 0.5*s), -- Left bottom front | |
vec3( 0.5*s, -0.5*s, 0.5*s), -- Right bottom front | |
vec3( 0.5*s, 0.5*s, 0.5*s), -- Right top front | |
vec3(-0.5*s, 0.5*s, 0.5*s), -- Left top front | |
vec3(-0.5*s, -0.5*s, -0.5*s), -- Left bottom back | |
vec3( 0.5*s, -0.5*s, -0.5*s), -- Right bottom back | |
vec3( 0.5*s, 0.5*s, -0.5*s), -- Right top back | |
vec3(-0.5*s, 0.5*s, -0.5*s), -- Left top back | |
} | |
-- now construct a cube out of the vertices above | |
v = { | |
-- Front | |
vertices[1], vertices[2], vertices[3], | |
vertices[1], vertices[3], vertices[4], | |
-- Right | |
vertices[2], vertices[6], vertices[7], | |
vertices[2], vertices[7], vertices[3], | |
-- Back | |
vertices[6], vertices[5], vertices[8], | |
vertices[6], vertices[8], vertices[7], | |
-- Left | |
vertices[5], vertices[1], vertices[4], | |
vertices[5], vertices[4], vertices[8], | |
-- Top | |
vertices[4], vertices[3], vertices[7], | |
vertices[4], vertices[7], vertices[8], | |
-- Bottom | |
vertices[5], vertices[6], vertices[2], | |
vertices[5], vertices[2], vertices[1], | |
} | |
return v | |
end | |
function Primitive:Sphere(depth) | |
local t = (1 + math.sqrt(5)) / 2 | |
--all the vertices of an icosohedron | |
local vertices = { | |
vec3(-1 , t, 0):normalize(), | |
vec3(1 , t, 0):normalize(), | |
vec3(-1 , -t, 0):normalize(), | |
vec3(1 , -t, 0):normalize(), | |
vec3(0 , -1, t):normalize(), | |
vec3(0 , 1, t):normalize(), | |
vec3(0 , -1, -t):normalize(), | |
vec3(0 , 1, -t):normalize(), | |
vec3(t , 0, -1):normalize(), | |
vec3(t , 0, 1):normalize(), | |
vec3(-t , 0, -1):normalize(), | |
vec3(-t , 0, 1):normalize() | |
} | |
--20 faces | |
icovertices = { | |
-- 5 faces around point 0 | |
vertices[1], vertices[12], vertices[6], | |
vertices[1], vertices[6], vertices[2], | |
vertices[1], vertices[2], vertices[8], | |
vertices[1], vertices[8], vertices[11], | |
vertices[1], vertices[11], vertices[12], | |
-- 5 adjacent faces | |
vertices[2], vertices[6], vertices[10], | |
vertices[6], vertices[12], vertices[5], | |
vertices[12], vertices[11], vertices[3], | |
vertices[11], vertices[8], vertices[7], | |
vertices[8], vertices[2], vertices[9], | |
-- 5 faces around point 3 | |
vertices[4], vertices[10], vertices[5], | |
vertices[4], vertices[5], vertices[3], | |
vertices[4], vertices[3], vertices[7], | |
vertices[4], vertices[7], vertices[9], | |
vertices[4], vertices[9], vertices[10], | |
--5 adjacent faces | |
vertices[5], vertices[10], vertices[6], | |
vertices[3], vertices[5], vertices[12], | |
vertices[7], vertices[3], vertices[11], | |
vertices[9], vertices[7], vertices[8], | |
vertices[10], vertices[9], vertices[2] | |
} | |
local finalVertices = {} | |
--divide each triangle into 4 sub triangles to make an isosphere | |
--this can be repeated (based on depth) for higher res spheres | |
for j=1,depth do | |
for i=1,#icovertices/3 do | |
midpoint1 = ((icovertices[i*3-2] + icovertices[i*3-1])/2):normalize() | |
midpoint2 = ((icovertices[i*3-1] + icovertices[i*3])/2):normalize() | |
midpoint3 = ((icovertices[i*3] + icovertices[i*3-2])/2):normalize() | |
--triangle 1 | |
table.insert(finalVertices,icovertices[i*3-2]) | |
table.insert(finalVertices,midpoint1) | |
table.insert(finalVertices,midpoint3) | |
--triangle 2 | |
table.insert(finalVertices,midpoint1) | |
table.insert(finalVertices,icovertices[i*3-1]) | |
table.insert(finalVertices,midpoint2) | |
--triangle 3 | |
table.insert(finalVertices,midpoint2) | |
table.insert(finalVertices,icovertices[i*3]) | |
table.insert(finalVertices,midpoint3) | |
--triangle 4 | |
table.insert(finalVertices,midpoint1) | |
table.insert(finalVertices,midpoint2) | |
table.insert(finalVertices,midpoint3) | |
end | |
icovertices = finalVertices | |
finalVertices = {} | |
end | |
return icovertices | |
end | |
--# BoneTree | |
--class to contain a tree of related bones and handled passing transforms down the tree | |
--also provides the helper for transforming the mesh to bone space | |
--also contains the shader for vertex skinning (hard coded to 15 bones and non optimal at this time) | |
BoneTree = class() | |
function BoneTree:init(m, tag) | |
self.baseMatrix = m | |
self.riggingInverseMatrix = m:inverse() | |
self.currentTransform = matrix() | |
self.currentInheritence = matrix() | |
self.outMatrix = self.riggingInverseMatrix * m | |
self.parent = nil | |
self.tag = tag | |
self.children = {} | |
end | |
function BoneTree:addChild(m, tag) | |
x = BoneTree(m, tag) | |
x.currentInheritence = self.baseMatrix * self.currentInheritence --* self.currentTransform | |
x.riggingInverseMatrix = (x.baseMatrix * x.currentInheritence):inverse() | |
x.outMatrix = x.riggingInverseMatrix * x.baseMatrix * x.currentInheritence | |
x.parent = self | |
table.insert(self.children, x) | |
return x | |
end | |
function BoneTree:applyTransform(m) | |
self.currentTransform = m | |
--self.outMatrix = self.baseMatrix * self.currentInheritence * self.currentTransform | |
local aggregateTransform = self.currentTransform * self.baseMatrix * self.currentInheritence | |
self.outMatrix = self.riggingInverseMatrix * aggregateTransform | |
for k,v in ipairs(self.children) do | |
v:applyInheritence(aggregateTransform) | |
end | |
end | |
function BoneTree:applyInheritence(m) | |
self.currentInheritence = m | |
--self.outMatrix = self.baseMatrix * self.currentInheritence * self.currentTransform | |
local aggregateTransform = self.currentTransform * self.baseMatrix * self.currentInheritence | |
self.outMatrix = self.riggingInverseMatrix * aggregateTransform | |
for k,v in ipairs(self.children) do | |
v:applyInheritence(aggregateTransform) | |
end | |
end | |
function BoneTree:retrieveBones(t) | |
table.insert(t, self.outMatrix) | |
for k,v in ipairs(self.children) do | |
v:retrieveBones(t) | |
end | |
end | |
function BoneTree:retrieveDebugBones(t) | |
table.insert(t, self.currentTransform * self.baseMatrix * self.currentInheritence) | |
for k,v in ipairs(self.children) do | |
v:retrieveDebugBones(t) | |
end | |
end | |
function BoneTree:retrieveByTag(tag) | |
if self.tag == tag then | |
return self | |
end | |
for k,v in ipairs(self.children) do | |
x = v:retrieveByTag(tag) | |
if x ~= nil then | |
return x | |
end | |
end | |
return nil | |
end | |
function BoneTree:retrieveBoneVectors(t, startPoint, parentBone) | |
curPoint = matrixByVector(self.outMatrix, vec4(0,0,0,1)) | |
thisBone = #t + 1 | |
if startPoint == nil then | |
table.insert(t, {startPoint = nil, endPoint = nil, nearBones = {} }) | |
else | |
table.insert(t, {startPoint = startPoint, endPoint = curPoint, nearBones = {}, controllingBone = parentBone }) | |
if parentBone ~= nil then | |
table.insert(t[thisBone].nearBones, parentBone) | |
end | |
end | |
for k,v in ipairs(self.children) do | |
table.insert(t[thisBone].nearBones, #t+1) | |
v:retrieveBoneVectors(t, curPoint, thisBone) | |
end | |
end | |
--debug printout of the bone tree | |
function BoneTree:traverse(x) | |
print(x..self.tag) | |
for k,v in ipairs(self.children) do | |
v:traverse(x.."-") | |
end | |
end | |
--shader("Documents:xxxxxx") | |
boneShader = { | |
vertexShader = [[ | |
// | |
// A basic vertex shader | |
// | |
//This is the current model * view * projection matrix | |
// Codea sets it automatically | |
uniform mat4 modelViewProjection; | |
uniform mat4 bones1; | |
uniform mat4 bones2; | |
uniform mat4 bones3; | |
uniform mat4 bones4; | |
uniform mat4 bones5; | |
uniform mat4 bones6; | |
uniform mat4 bones7; | |
uniform mat4 bones8; | |
uniform mat4 bones9; | |
uniform mat4 bones10; | |
uniform mat4 bones11; | |
uniform mat4 bones12; | |
uniform mat4 bones13; | |
uniform mat4 bones14; | |
uniform mat4 bones15; | |
//This is the current mesh vertex position, color and tex coord | |
// Set automatically | |
attribute vec4 position; | |
attribute vec4 color; | |
attribute vec2 texCoord; | |
attribute vec4 boneWeight; | |
//This is an output variable that will be passed to the fragment shader | |
varying lowp vec4 vColor; | |
varying highp vec2 vTexCoord; | |
void main() | |
{ | |
vec4 outv = position; | |
if (boneWeight.x == 1.0) { | |
outv = bones1 * position * boneWeight.y; | |
} | |
if (boneWeight.x == 2.0) { | |
outv = bones2 * position * boneWeight.y; | |
} | |
if (boneWeight.x == 3.0) { | |
outv = bones3 * position * boneWeight.y; | |
} | |
if (boneWeight.x == 4.0) { | |
outv = bones4 * position * boneWeight.y; | |
} | |
if (boneWeight.x == 5.0) { | |
outv = bones5 * position * boneWeight.y; | |
} | |
if (boneWeight.x == 6.0) { | |
outv = bones6 * position * boneWeight.y; | |
} | |
if (boneWeight.x == 7.0) { | |
outv = bones7 * position * boneWeight.y; | |
} | |
if (boneWeight.x == 8.0) { | |
outv = bones8 * position * boneWeight.y; | |
} | |
if (boneWeight.x == 9.0) { | |
outv = bones9 * position * boneWeight.y; | |
} | |
if (boneWeight.x == 10.0) { | |
outv = bones10 * position * boneWeight.y; | |
} | |
if (boneWeight.x == 11.0) { | |
outv = bones11 * position * boneWeight.y; | |
} | |
if (boneWeight.x == 12.0) { | |
outv = bones12 * position * boneWeight.y; | |
} | |
if (boneWeight.x == 13.0) { | |
outv = bones13 * position * boneWeight.y; | |
} | |
if (boneWeight.x == 14.0) { | |
outv = bones14 * position * boneWeight.y; | |
} | |
if (boneWeight.x == 15.0) { | |
outv = bones15 * position * boneWeight.y; | |
} | |
if (boneWeight.z == 1.0) { | |
outv += bones1 * position * boneWeight.w; | |
} | |
if (boneWeight.z == 2.0) { | |
outv += bones2 * position * boneWeight.w; | |
} | |
if (boneWeight.z == 3.0) { | |
outv += bones3 * position * boneWeight.w; | |
} | |
if (boneWeight.z == 4.0) { | |
outv += bones4 * position * boneWeight.w; | |
} | |
if (boneWeight.z == 5.0) { | |
outv += bones5 * position * boneWeight.w; | |
} | |
if (boneWeight.z == 6.0) { | |
outv += bones6 * position * boneWeight.w; | |
} | |
if (boneWeight.z == 7.0) { | |
outv += bones7 * position * boneWeight.w; | |
} | |
if (boneWeight.z == 8.0) { | |
outv += bones8 * position * boneWeight.w; | |
} | |
if (boneWeight.z == 9.0) { | |
outv += bones9 * position * boneWeight.w; | |
} | |
if (boneWeight.z == 10.0) { | |
outv += bones10 * position * boneWeight.w; | |
} | |
if (boneWeight.z == 11.0) { | |
outv += bones11 * position * boneWeight.w; | |
} | |
if (boneWeight.z == 12.0) { | |
outv += bones12 * position * boneWeight.w; | |
} | |
if (boneWeight.z == 13.0) { | |
outv += bones13 * position * boneWeight.w; | |
} | |
if (boneWeight.z == 14.0) { | |
outv += bones14 * position * boneWeight.w; | |
} | |
if (boneWeight.z == 15.0) { | |
outv += bones15 * position * boneWeight.w; | |
} | |
//Pass the mesh color to the fragment shader | |
vColor = color; | |
vTexCoord = texCoord; | |
//Multiply the vertex position by our combined transform | |
gl_Position = modelViewProjection * outv; | |
} | |
]], | |
fragmentShader = [[ | |
// | |
// A basic fragment shader | |
// | |
//Default precision qualifier | |
precision highp float; | |
//This represents the current texture on the mesh | |
uniform lowp sampler2D texture; | |
//The interpolated vertex color for this fragment | |
varying lowp vec4 vColor; | |
//The interpolated texture coordinate for this fragment | |
varying highp vec2 vTexCoord; | |
void main() | |
{ | |
//Sample the texture at the interpolated coordinate | |
//lowp vec4 col = texture2D( texture, vTexCoord ) * vColor; | |
//Set the output color to the texture color | |
gl_FragColor = vColor; | |
} | |
]] | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment