refactor body and light code to minimize size of monolithic method

This commit is contained in:
Tim Anema 2014-09-26 18:11:23 -04:00
parent fd58dd6a86
commit 08e50a7b2a
3 changed files with 321 additions and 285 deletions

View File

@ -523,4 +523,119 @@ function body:setShadowType(type, ...)
end end
end end
function body:drawShadow(light)
if self.alpha < 1.0 then
love.graphics.setBlendMode("multiplicative")
love.graphics.setColor(self.red, self.green, self.blue)
if self.shadowType == "circle" then
love.graphics.circle("fill", self.x - self.ox, self.y - self.oy, self.radius)
elseif self.shadowType == "rectangle" then
love.graphics.rectangle("fill", self.x - self.ox, self.y - self.oy, self.width, self.height)
elseif self.shadowType == "polygon" then
love.graphics.polygon("fill", unpack(self.data))
end
end
if self.shadowType == "image" and self.img then
love.graphics.setBlendMode("alpha")
local length = 1.0
local shadowRotation = math.atan2((self.x) - light.x, (self.y + self.oy) - light.y)
self.shadowVert = {
{math.sin(shadowRotation) * self.imgHeight * length, (length * math.cos(shadowRotation) + 1.0) * self.imgHeight + (math.cos(shadowRotation) + 1.0) * self.shadowY, 0, 0, self.red, self.green, self.blue, self.alpha * self.fadeStrength * 255},
{self.imgWidth + math.sin(shadowRotation) * self.imgHeight * length, (length * math.cos(shadowRotation) + 1.0) * self.imgHeight + (math.cos(shadowRotation) + 1.0) * self.shadowY, 1, 0, self.red, self.green, self.blue, self.alpha * self.fadeStrength * 255},
{self.imgWidth, self.imgHeight + (math.cos(shadowRotation) + 1.0) * self.shadowY, 1, 1, self.red, self.green, self.blue, self.alpha * 255},
{0, self.imgHeight + (math.cos(shadowRotation) + 1.0) * self.shadowY, 0, 1, self.red, self.green, self.blue, self.alpha * 255}
}
self.shadowMesh:setVertices(self.shadowVert)
love.graphics.draw(self.shadowMesh, self.x - self.ox + self.world.translate_x, self.y - self.oy + self.world.translate_y)
end
end
function body:drawPixelShadow()
if self.type == "image" and self.normalMesh then
love.graphics.setColor(255, 255, 255)
love.graphics.draw(self.normalMesh, self.x - self.nx + self.world.translate_x, self.y - self.ny + self.world.translate_y)
end
end
function body:drawGlow()
if self.glowStrength > 0.0 then
love.graphics.setColor(self.glowRed * self.glowStrength, self.glowGreen * self.glowStrength, self.glowBlue * self.glowStrength)
else
love.graphics.setColor(0, 0, 0)
end
if self.type == "circle" then
love.graphics.circle("fill", self.x, self.y, self.radius)
elseif self.type == "rectangle" then
love.graphics.rectangle("fill", self.x, self.y, self.width, self.height)
elseif self.type == "polygon" then
love.graphics.polygon("fill", unpack(self.data))
elseif self.type == "image" and self.img then
if self.glowStrength > 0.0 and self.glow then
love.graphics.setShader(self.world.glowShader)
self.world.glowShader:send("glowImage", self.glow)
self.world.glowShader:send("glowTime", love.timer.getTime() * 0.5)
love.graphics.setColor(255, 255, 255)
else
love.graphics.setShader()
love.graphics.setColor(0, 0, 0)
end
love.graphics.draw(self.img, self.x - self.ix + self.world.translate_x, self.y - self.iy + self.world.translate_y)
end
end
function body:drawRefraction()
if self.refraction and self.normal then
love.graphics.setColor(255, 255, 255)
if self.tileX == 0.0 and self.tileY == 0.0 then
love.graphics.draw(normal, self.x - self.nx + self.world.translate_x, self.y - self.ny + self.world.translate_y)
else
self.normalMesh:setVertices(self.normalVert)
love.graphics.draw(self.normalMesh, self.x - self.nx + self.world.translate_x, self.y - self.ny + self.world.translate_y)
end
end
love.graphics.setColor(0, 0, 0)
if not self.refractive then
if self.type == "circle" then
love.graphics.circle("fill", self.x, self.y, self.radius)
elseif self.type == "rectangle" then
love.graphics.rectangle("fill", self.x, self.y, self.width, self.height)
elseif self.type == "polygon" then
love.graphics.polygon("fill", unpack(self.data))
elseif self.type == "image" and self.img then
love.graphics.draw(self.img, self.x - self.ix + self.world.translate_x, self.y - self.iy + self.world.translate_y)
end
end
end
function body:drawReflection()
if self.reflection and self.normal then
love.graphics.setColor(255, 0, 0)
self.normalMesh:setVertices(self.normalVert)
love.graphics.draw(self.normalMesh, self.x - self.nx + self.world.translate_x, self.y - self.ny + self.world.translate_y)
end
if self.reflective and self.img then
love.graphics.setColor(0, 255, 0)
love.graphics.draw(self.img, self.x - self.ix + self.world.translate_x, self.y - self.iy + self.world.translate_y)
elseif not self.reflection and self.img then
love.graphics.setColor(0, 0, 0)
love.graphics.draw(self.img, self.x - self.ix + self.world.translate_x, self.y - self.iy + self.world.translate_y)
end
end
function body:drawMaterial()
if self.material and self.normal then
love.graphics.setColor(255, 255, 255)
self.world.materialShader:send("material", self.material)
love.graphics.draw(self.normal, self.x - self.nx + self.world.translate_x, self.y - self.ny + self.world.translate_y)
end
end
return body return body

View File

@ -1,5 +1,7 @@
local _PACKAGE = (...):match("^(.+)[%./][^%./]+") or "" local _PACKAGE = (...):match("^(.+)[%./][^%./]+") or ""
local class = require(_PACKAGE.."/class") local class = require(_PACKAGE.."/class")
local stencils = require(_PACKAGE..'/stencils')
local vector = require(_PACKAGE..'/vector')
local light = class() local light = class()
@ -122,4 +124,198 @@ function light:getType()
return "light" return "light"
end end
function light:updateShadow()
if self.changed or self.changed then
if self.x + self.range > self.world.translate_x and self.x - self.range < love.graphics.getWidth() + self.world.translate_x
and self.y + self.range > self.world.translate_y and self.y - self.range < love.graphics.getHeight() + self.world.translate_y
then
local lightposrange = {self.x, love.graphics.getHeight() - self.y, self.range}
local light = self
self.world.direction = self.world.direction + 0.002
self.world.shader:send("lightPosition", {self.x - self.world.translate_x, love.graphics.getHeight() - (self.y - self.world.translate_y), self.z})
self.world.shader:send("lightRange", self.range)
self.world.shader:send("lightColor", {self.red / 255.0, self.green / 255.0, self.blue / 255.0})
self.world.shader:send("lightSmooth", self.smooth)
self.world.shader:send("lightGlow", {1.0 - self.glowSize, self.glowStrength})
self.world.shader:send("lightAngle", math.pi - self.angle / 2.0)
self.world.shader:send("lightDirection", self.direction)
love.graphics.setCanvas(self.shadow)
love.graphics.clear()
-- calculate shadows
local shadow_geometry = calculateShadows(light, self.world.body)
-- draw shadow
love.graphics.setInvertedStencil(stencils.shadow(shadow_geometry, self.world.body))
love.graphics.setBlendMode("additive")
-- FIND THIS TOOOO
love.graphics.rectangle("fill", self.world.translate_x, self.world.translate_y, love.graphics.getWidth(), love.graphics.getHeight())
-- draw color shadows
love.graphics.setBlendMode("multiplicative")
love.graphics.setShader()
for k = 1,#shadow_geometry do
if shadow_geometry[k].alpha < 1.0 then
love.graphics.setColor(
shadow_geometry[k].red * (1.0 - shadow_geometry[k].alpha),
shadow_geometry[k].green * (1.0 - shadow_geometry[k].alpha),
shadow_geometry[k].blue * (1.0 - shadow_geometry[k].alpha)
)
love.graphics.polygon("fill", unpack(shadow_geometry[k]))
end
end
for k = 1, #self.world.body do
self.world.body[k]:drawShadow(self)
end
love.graphics.setShader(self.world.shader)
-- draw shine
love.graphics.setCanvas(self.shine)
self.shine:clear(255, 255, 255)
love.graphics.setBlendMode("alpha")
love.graphics.setStencil(stencils.poly(self.world.body))
-- WHOA THIS MAY BE THE ISSUE HERE FIND THIS!
love.graphics.rectangle("fill", self.world.translate_x, self.world.translate_y, love.graphics.getWidth(), love.graphics.getHeight())
self.visible = true
else
self.visible = false
end
self.changed = self.world.changed
end
end
function light:drawShadow()
if self.visible then
love.graphics.draw(self.shadow, self.world.translate_x, self.world.translate_y)
end
end
function light:drawShine()
if self.visible then
love.graphics.draw(self.shine, self.world.translate_x, self.world.translate_y)
end
end
function calculateShadows(light, body)
local shadowGeometry = {}
local shadowLength = 100000
for i = 1, #body do
if body[i].shadowType == "rectangle" or body[i].shadowType == "polygon" then
curPolygon = body[i].data
if not body[i].castsNoShadow then
local edgeFacingTo = {}
for k = 1, #curPolygon, 2 do
local indexOfNextVertex = (k + 2) % #curPolygon
local normal = {-curPolygon[indexOfNextVertex+1] + curPolygon[k + 1], curPolygon[indexOfNextVertex] - curPolygon[k]}
local lightToPoint = {curPolygon[k] - light.x, curPolygon[k + 1] - light.y}
normal = vector.normalize(normal)
lightToPoint = vector.normalize(lightToPoint)
local dotProduct = vector.dot(normal, lightToPoint)
if dotProduct > 0 then table.insert(edgeFacingTo, true)
else table.insert(edgeFacingTo, false) end
end
local curShadowGeometry = {}
for k = 1, #edgeFacingTo do
local nextIndex = (k + 1) % #edgeFacingTo
if nextIndex == 0 then nextIndex = #edgeFacingTo end
if edgeFacingTo[k] and not edgeFacingTo[nextIndex] then
curShadowGeometry[1] = curPolygon[nextIndex*2-1]
curShadowGeometry[2] = curPolygon[nextIndex*2]
local lightVecFrontBack = vector.normalize({curPolygon[nextIndex*2-1] - light.x, curPolygon[nextIndex*2] - light.y})
curShadowGeometry[3] = curShadowGeometry[1] + lightVecFrontBack[1] * shadowLength
curShadowGeometry[4] = curShadowGeometry[2] + lightVecFrontBack[2] * shadowLength
elseif not edgeFacingTo[k] and edgeFacingTo[nextIndex] then
curShadowGeometry[7] = curPolygon[nextIndex*2-1]
curShadowGeometry[8] = curPolygon[nextIndex*2]
local lightVecBackFront = vector.normalize({curPolygon[nextIndex*2-1] - light.x, curPolygon[nextIndex*2] - light.y})
curShadowGeometry[5] = curShadowGeometry[7] + lightVecBackFront[1] * shadowLength
curShadowGeometry[6] = curShadowGeometry[8] + lightVecBackFront[2] * shadowLength
end
end
if curShadowGeometry[1]
and curShadowGeometry[2]
and curShadowGeometry[3]
and curShadowGeometry[4]
and curShadowGeometry[5]
and curShadowGeometry[6]
and curShadowGeometry[7]
and curShadowGeometry[8]
then
curShadowGeometry.alpha = body[i].alpha
curShadowGeometry.red = body[i].red
curShadowGeometry.green = body[i].green
curShadowGeometry.blue = body[i].blue
shadowGeometry[#shadowGeometry + 1] = curShadowGeometry
end
end
elseif body[i].shadowType == "circle" then
if not body[i].castsNoShadow then
local length = math.sqrt(math.pow(light.x - (body[i].x - body[i].ox), 2) + math.pow(light.y - (body[i].y - body[i].oy), 2))
if length >= body[i].radius and length <= light.range then
local curShadowGeometry = {}
local angle = math.atan2(light.x - (body[i].x - body[i].ox), (body[i].y - body[i].oy) - light.y) + math.pi / 2
local x2 = ((body[i].x - body[i].ox) + math.sin(angle) * body[i].radius)
local y2 = ((body[i].y - body[i].oy) - math.cos(angle) * body[i].radius)
local x3 = ((body[i].x - body[i].ox) - math.sin(angle) * body[i].radius)
local y3 = ((body[i].y - body[i].oy) + math.cos(angle) * body[i].radius)
curShadowGeometry[1] = x2
curShadowGeometry[2] = y2
curShadowGeometry[3] = x3
curShadowGeometry[4] = y3
curShadowGeometry[5] = x3 - (light.x - x3) * shadowLength
curShadowGeometry[6] = y3 - (light.y - y3) * shadowLength
curShadowGeometry[7] = x2 - (light.x - x2) * shadowLength
curShadowGeometry[8] = y2 - (light.y - y2) * shadowLength
curShadowGeometry.alpha = body[i].alpha
curShadowGeometry.red = body[i].red
curShadowGeometry.green = body[i].green
curShadowGeometry.blue = body[i].blue
shadowGeometry[#shadowGeometry + 1] = curShadowGeometry
end
end
end
end
return shadowGeometry
end
function light:drawPixelShadow()
if self.visible then
if self.normalInvert then
self.world.normalInvertShader:send('screenResolution', {love.graphics.getWidth(), love.graphics.getHeight()})
self.world.normalInvertShader:send('lightColor', {self.red / 255.0, self.green / 255.0, self.blue / 255.0})
self.world.normalInvertShader:send('lightPosition',{self.x, love.graphics.getHeight() - self.y, self.z / 255.0})
self.world.normalInvertShader:send('lightRange',{self.range})
self.world.normalInvertShader:send("lightSmooth", self.smooth)
self.world.normalInvertShader:send("lightAngle", math.pi - self.angle / 2.0)
self.world.normalInvertShader:send("lightDirection", self.direction)
love.graphics.setShader(self.world.normalInvertShader)
else
self.world.normalShader:send('screenResolution', {love.graphics.getWidth(), love.graphics.getHeight()})
self.world.normalShader:send('lightColor', {self.red / 255.0, self.green / 255.0, self.blue / 255.0})
self.world.normalShader:send('lightPosition',{self.x, love.graphics.getHeight() - self.y, self.z / 255.0})
self.world.normalShader:send('lightRange',{self.range})
self.world.normalShader:send("lightSmooth", self.smooth)
self.world.normalShader:send("lightAngle", math.pi - self.angle / 2.0)
self.world.normalShader:send("lightDirection", self.direction)
love.graphics.setShader(self.world.normalShader)
end
love.graphics.draw(self.world.normalMap, self.world.translate_x, self.world.translate_y)
end
end
return light return light

View File

@ -23,8 +23,6 @@ SOFTWARE.
]] ]]
local _PACKAGE = (...):match("^(.+)[%./][^%./]+") or "" local _PACKAGE = (...):match("^(.+)[%./][^%./]+") or ""
local class = require(_PACKAGE..'/class') local class = require(_PACKAGE..'/class')
local stencils = require(_PACKAGE..'/stencils')
local vector = require(_PACKAGE..'/vector')
local Light = require(_PACKAGE..'/light') local Light = require(_PACKAGE..'/light')
local Body = require(_PACKAGE..'/body') local Body = require(_PACKAGE..'/body')
@ -111,97 +109,8 @@ function light_world:update()
if self.optionShadows and (self.isShadows or self.isLight) then if self.optionShadows and (self.isShadows or self.isLight) then
love.graphics.setShader(self.shader) love.graphics.setShader(self.shader)
local lightsOnScreen = 0
for i = 1, #self.lights do for i = 1, #self.lights do
if self.lights[i].changed or self.changed then self.lights[i]:updateShadow()
if self.lights[i].x + self.lights[i].range > self.translate_x and self.lights[i].x - self.lights[i].range < love.graphics.getWidth() + self.translate_x
and self.lights[i].y + self.lights[i].range > self.translate_y and self.lights[i].y - self.lights[i].range < love.graphics.getHeight() + self.translate_y
then
local lightposrange = {self.lights[i].x, love.graphics.getHeight() - self.lights[i].y, self.lights[i].range}
local light = self.lights[i]
self.direction = self.direction + 0.002
self.shader:send("lightPosition", {self.lights[i].x - self.translate_x, love.graphics.getHeight() - (self.lights[i].y - self.translate_y), self.lights[i].z})
self.shader:send("lightRange", self.lights[i].range)
self.shader:send("lightColor", {self.lights[i].red / 255.0, self.lights[i].green / 255.0, self.lights[i].blue / 255.0})
self.shader:send("lightSmooth", self.lights[i].smooth)
self.shader:send("lightGlow", {1.0 - self.lights[i].glowSize, self.lights[i].glowStrength})
self.shader:send("lightAngle", math.pi - self.lights[i].angle / 2.0)
self.shader:send("lightDirection", self.lights[i].direction)
love.graphics.setCanvas(self.lights[i].shadow)
love.graphics.clear()
-- calculate shadows
local shadow_geometry = calculateShadows(light, self.body)
-- draw shadow
love.graphics.setInvertedStencil(stencils.shadow(shadow_geometry, self.body))
love.graphics.setBlendMode("additive")
love.graphics.rectangle("fill", self.translate_x, self.translate_y, love.graphics.getWidth(), love.graphics.getHeight())
-- draw color shadows
love.graphics.setBlendMode("multiplicative")
love.graphics.setShader()
for k = 1,#shadow_geometry do
if shadow_geometry[k].alpha < 1.0 then
love.graphics.setColor(
shadow_geometry[k].red * (1.0 - shadow_geometry[k].alpha),
shadow_geometry[k].green * (1.0 - shadow_geometry[k].alpha),
shadow_geometry[k].blue * (1.0 - shadow_geometry[k].alpha)
)
love.graphics.polygon("fill", unpack(shadow_geometry[k]))
end
end
for k = 1, #self.body do
if self.body[k].alpha < 1.0 then
love.graphics.setBlendMode("multiplicative")
love.graphics.setColor(self.body[k].red, self.body[k].green, self.body[k].blue)
if self.body[k].shadowType == "circle" then
love.graphics.circle("fill", self.body[k].x - self.body[k].ox, self.body[k].y - self.body[k].oy, self.body[k].radius)
elseif self.body[k].shadowType == "rectangle" then
love.graphics.rectangle("fill", self.body[k].x - self.body[k].ox, self.body[k].y - self.body[k].oy, self.body[k].width, self.body[k].height)
elseif self.body[k].shadowType == "polygon" then
love.graphics.polygon("fill", unpack(self.body[k].data))
end
end
if self.body[k].shadowType == "image" and self.body[k].img then
love.graphics.setBlendMode("alpha")
local length = 1.0
local shadowRotation = math.atan2((self.body[k].x) - self.lights[i].x, (self.body[k].y + self.body[k].oy) - self.lights[i].y)
--local alpha = math.abs(math.cos(shadowRotation))
self.body[k].shadowVert = {
{math.sin(shadowRotation) * self.body[k].imgHeight * length, (length * math.cos(shadowRotation) + 1.0) * self.body[k].imgHeight + (math.cos(shadowRotation) + 1.0) * self.body[k].shadowY, 0, 0, self.body[k].red, self.body[k].green, self.body[k].blue, self.body[k].alpha * self.body[k].fadeStrength * 255},
{self.body[k].imgWidth + math.sin(shadowRotation) * self.body[k].imgHeight * length, (length * math.cos(shadowRotation) + 1.0) * self.body[k].imgHeight + (math.cos(shadowRotation) + 1.0) * self.body[k].shadowY, 1, 0, self.body[k].red, self.body[k].green, self.body[k].blue, self.body[k].alpha * self.body[k].fadeStrength * 255},
{self.body[k].imgWidth, self.body[k].imgHeight + (math.cos(shadowRotation) + 1.0) * self.body[k].shadowY, 1, 1, self.body[k].red, self.body[k].green, self.body[k].blue, self.body[k].alpha * 255},
{0, self.body[k].imgHeight + (math.cos(shadowRotation) + 1.0) * self.body[k].shadowY, 0, 1, self.body[k].red, self.body[k].green, self.body[k].blue, self.body[k].alpha * 255}
}
self.body[k].shadowMesh:setVertices(self.body[k].shadowVert)
love.graphics.draw(self.body[k].shadowMesh, self.body[k].x - self.body[k].ox + self.translate_x, self.body[k].y - self.body[k].oy + self.translate_y)
end
end
love.graphics.setShader(self.shader)
-- draw shine
love.graphics.setCanvas(self.lights[i].shine)
self.lights[i].shine:clear(255, 255, 255)
love.graphics.setBlendMode("alpha")
love.graphics.setStencil(stencils.poly(self.body))
love.graphics.rectangle("fill", self.translate_x, self.translate_y, love.graphics.getWidth(), love.graphics.getHeight())
lightsOnScreen = lightsOnScreen + 1
self.lights[i].visible = true
else
self.lights[i].visible = false
end
self.lights[i].changed = self.changed
end
end end
-- update shadow -- update shadow
@ -214,9 +123,7 @@ function light_world:update()
love.graphics.setColor(255, 255, 255) love.graphics.setColor(255, 255, 255)
love.graphics.setBlendMode("additive") love.graphics.setBlendMode("additive")
for i = 1, #self.lights do for i = 1, #self.lights do
if self.lights[i].visible then self.lights[i]:drawShadow()
love.graphics.draw(self.lights[i].shadow, self.translate_x, self.translate_y)
end
end end
self.isShadowBlur = false self.isShadowBlur = false
@ -228,9 +135,7 @@ function light_world:update()
love.graphics.setColor(255, 255, 255) love.graphics.setColor(255, 255, 255)
love.graphics.setBlendMode("additive") love.graphics.setBlendMode("additive")
for i = 1, #self.lights do for i = 1, #self.lights do
if self.lights[i].visible then self.lights[i]:drawShine()
love.graphics.draw(self.lights[i].shine, self.translate_x, self.translate_y)
end
end end
end end
@ -243,10 +148,7 @@ function light_world:update()
love.graphics.setShader() love.graphics.setShader()
love.graphics.setCanvas(self.normalMap) love.graphics.setCanvas(self.normalMap)
for i = 1, #self.body do for i = 1, #self.body do
if self.body[i].type == "image" and self.body[i].normalMesh then self.body[i]:drawPixelShadow()
love.graphics.setColor(255, 255, 255)
love.graphics.draw(self.body[i].normalMesh, self.body[i].x - self.body[i].nx + self.translate_x, self.body[i].y - self.body[i].ny + self.translate_y)
end
end end
love.graphics.setColor(255, 255, 255) love.graphics.setColor(255, 255, 255)
love.graphics.setBlendMode("alpha") love.graphics.setBlendMode("alpha")
@ -257,28 +159,7 @@ function light_world:update()
love.graphics.setShader(self.shader2) love.graphics.setShader(self.shader2)
for i = 1, #self.lights do for i = 1, #self.lights do
if self.lights[i].visible then self.lights[i]:drawPixelShadow()
if self.normalInvert then
self.normalInvertShader:send('screenResolution', {love.graphics.getWidth(), love.graphics.getHeight()})
self.normalInvertShader:send('lightColor', {self.lights[i].red / 255.0, self.lights[i].green / 255.0, self.lights[i].blue / 255.0})
self.normalInvertShader:send('lightPosition',{self.lights[i].x, love.graphics.getHeight() - self.lights[i].y, self.lights[i].z / 255.0})
self.normalInvertShader:send('lightRange',{self.lights[i].range})
self.normalInvertShader:send("lightSmooth", self.lights[i].smooth)
self.normalInvertShader:send("lightAngle", math.pi - self.lights[i].angle / 2.0)
self.normalInvertShader:send("lightDirection", self.lights[i].direction)
love.graphics.setShader(self.normalInvertShader)
else
self.normalShader:send('screenResolution', {love.graphics.getWidth(), love.graphics.getHeight()})
self.normalShader:send('lightColor', {self.lights[i].red / 255.0, self.lights[i].green / 255.0, self.lights[i].blue / 255.0})
self.normalShader:send('lightPosition',{self.lights[i].x, love.graphics.getHeight() - self.lights[i].y, self.lights[i].z / 255.0})
self.normalShader:send('lightRange',{self.lights[i].range})
self.normalShader:send("lightSmooth", self.lights[i].smooth)
self.normalShader:send("lightAngle", math.pi - self.lights[i].angle / 2.0)
self.normalShader:send("lightDirection", self.lights[i].direction)
love.graphics.setShader(self.normalShader)
end
love.graphics.draw(self.normalMap, self.translate_x, self.translate_y)
end
end end
love.graphics.setShader() love.graphics.setShader()
@ -310,64 +191,17 @@ function light_world:update()
end end
for i = 1, #self.body do for i = 1, #self.body do
if self.body[i].glowStrength > 0.0 then self.body[i]:drawGlow()
love.graphics.setColor(self.body[i].glowRed * self.body[i].glowStrength, self.body[i].glowGreen * self.body[i].glowStrength, self.body[i].glowBlue * self.body[i].glowStrength)
else
love.graphics.setColor(0, 0, 0)
end
if self.body[i].type == "circle" then
love.graphics.circle("fill", self.body[i].x, self.body[i].y, self.body[i].radius)
elseif self.body[i].type == "rectangle" then
love.graphics.rectangle("fill", self.body[i].x, self.body[i].y, self.body[i].width, self.body[i].height)
elseif self.body[i].type == "polygon" then
love.graphics.polygon("fill", unpack(self.body[i].data))
elseif self.body[i].type == "image" and self.body[i].img then
if self.body[i].glowStrength > 0.0 and self.body[i].glow then
love.graphics.setShader(self.glowShader)
self.glowShader:send("glowImage", self.body[i].glow)
self.glowShader:send("glowTime", love.timer.getTime() * 0.5)
love.graphics.setColor(255, 255, 255)
else
love.graphics.setShader()
love.graphics.setColor(0, 0, 0)
end
love.graphics.draw(self.body[i].img, self.body[i].x - self.body[i].ix + self.translate_x, self.body[i].y - self.body[i].iy + self.translate_y)
end
end end
end end
if self.optionRefraction and self.isRefraction then if self.optionRefraction and self.isRefraction then
love.graphics.setShader() love.graphics.setShader()
-- create refraction map -- create refraction map
self.refractionMap:clear() self.refractionMap:clear()
love.graphics.setCanvas(self.refractionMap) love.graphics.setCanvas(self.refractionMap)
for i = 1, #self.body do for i = 1, #self.body do
if self.body[i].refraction and self.body[i].normal then self.body[i]:drawRefraction()
love.graphics.setColor(255, 255, 255)
if self.body[i].tileX == 0.0 and self.body[i].tileY == 0.0 then
love.graphics.draw(normal, self.body[i].x - self.body[i].nx + self.translate_x, self.body[i].y - self.body[i].ny + self.translate_y)
else
self.body[i].normalMesh:setVertices(self.body[i].normalVert)
love.graphics.draw(self.body[i].normalMesh, self.body[i].x - self.body[i].nx + self.translate_x, self.body[i].y - self.body[i].ny + self.translate_y)
end
end
end
love.graphics.setColor(0, 0, 0)
for i = 1, #self.body do
if not self.body[i].refractive then
if self.body[i].type == "circle" then
love.graphics.circle("fill", self.body[i].x, self.body[i].y, self.body[i].radius)
elseif self.body[i].type == "rectangle" then
love.graphics.rectangle("fill", self.body[i].x, self.body[i].y, self.body[i].width, self.body[i].height)
elseif self.body[i].type == "polygon" then
love.graphics.polygon("fill", unpack(self.body[i].data))
elseif self.body[i].type == "image" and self.body[i].img then
love.graphics.draw(self.body[i].img, self.body[i].x - self.body[i].ix + self.translate_x, self.body[i].y - self.body[i].iy + self.translate_y)
end
end
end end
end end
@ -377,20 +211,7 @@ function light_world:update()
self.reflectionMap:clear(0, 0, 0) self.reflectionMap:clear(0, 0, 0)
love.graphics.setCanvas(self.reflectionMap) love.graphics.setCanvas(self.reflectionMap)
for i = 1, #self.body do for i = 1, #self.body do
if self.body[i].reflection and self.body[i].normal then self.body[i]:drawReflection()
love.graphics.setColor(255, 0, 0)
self.body[i].normalMesh:setVertices(self.body[i].normalVert)
love.graphics.draw(self.body[i].normalMesh, self.body[i].x - self.body[i].nx + self.translate_x, self.body[i].y - self.body[i].ny + self.translate_y)
end
end
for i = 1, #self.body do
if self.body[i].reflective and self.body[i].img then
love.graphics.setColor(0, 255, 0)
love.graphics.draw(self.body[i].img, self.body[i].x - self.body[i].ix + self.translate_x, self.body[i].y - self.body[i].iy + self.translate_y)
elseif not self.body[i].reflection and self.body[i].img then
love.graphics.setColor(0, 0, 0)
love.graphics.draw(self.body[i].img, self.body[i].x - self.body[i].ix + self.translate_x, self.body[i].y - self.body[i].iy + self.translate_y)
end
end end
end end
end end
@ -488,11 +309,7 @@ end
function light_world:drawMaterial() function light_world:drawMaterial()
love.graphics.setShader(self.materialShader) love.graphics.setShader(self.materialShader)
for i = 1, #self.body do for i = 1, #self.body do
if self.body[i].material and self.body[i].normal then self.body[i]:drawMaterial()
love.graphics.setColor(255, 255, 255)
self.materialShader:send("material", self.body[i].material)
love.graphics.draw(self.body[i].normal, self.body[i].x - self.body[i].nx + self.translate_x, self.body[i].y - self.body[i].ny + self.translate_y)
end
end end
love.graphics.setShader() love.graphics.setShader()
end end
@ -563,7 +380,7 @@ function light_world:drawReflection()
end end
-- new light -- new light
function light_world:newLight(x, y, red, green, blue, range) function light_world:newLight(x, y, red, green, blue, range)
self.lights[#self.lights + 1] = Light(o, x, y, red, green, blue, range) self.lights[#self.lights + 1] = Light(self, x, y, red, green, blue, range)
self.isLight = true self.isLight = true
return self.lights[#self.lights] return self.lights[#self.lights]
end end
@ -739,98 +556,6 @@ function light_world:getType()
return "world" return "world"
end end
function calculateShadows(light, body)
local shadowGeometry = {}
local shadowLength = 100000
for i = 1, #body do
if body[i].shadowType == "rectangle" or body[i].shadowType == "polygon" then
curPolygon = body[i].data
if not body[i].castsNoShadow then
local edgeFacingTo = {}
for k = 1, #curPolygon, 2 do
local indexOfNextVertex = (k + 2) % #curPolygon
local normal = {-curPolygon[indexOfNextVertex+1] + curPolygon[k + 1], curPolygon[indexOfNextVertex] - curPolygon[k]}
local lightToPoint = {curPolygon[k] - light.x, curPolygon[k + 1] - light.y}
normal = vector.normalize(normal)
lightToPoint = vector.normalize(lightToPoint)
local dotProduct = vector.dot(normal, lightToPoint)
if dotProduct > 0 then table.insert(edgeFacingTo, true)
else table.insert(edgeFacingTo, false) end
end
local curShadowGeometry = {}
for k = 1, #edgeFacingTo do
local nextIndex = (k + 1) % #edgeFacingTo
if nextIndex == 0 then nextIndex = #edgeFacingTo end
if edgeFacingTo[k] and not edgeFacingTo[nextIndex] then
curShadowGeometry[1] = curPolygon[nextIndex*2-1]
curShadowGeometry[2] = curPolygon[nextIndex*2]
local lightVecFrontBack = vector.normalize({curPolygon[nextIndex*2-1] - light.x, curPolygon[nextIndex*2] - light.y})
curShadowGeometry[3] = curShadowGeometry[1] + lightVecFrontBack[1] * shadowLength
curShadowGeometry[4] = curShadowGeometry[2] + lightVecFrontBack[2] * shadowLength
elseif not edgeFacingTo[k] and edgeFacingTo[nextIndex] then
curShadowGeometry[7] = curPolygon[nextIndex*2-1]
curShadowGeometry[8] = curPolygon[nextIndex*2]
local lightVecBackFront = vector.normalize({curPolygon[nextIndex*2-1] - light.x, curPolygon[nextIndex*2] - light.y})
curShadowGeometry[5] = curShadowGeometry[7] + lightVecBackFront[1] * shadowLength
curShadowGeometry[6] = curShadowGeometry[8] + lightVecBackFront[2] * shadowLength
end
end
if curShadowGeometry[1]
and curShadowGeometry[2]
and curShadowGeometry[3]
and curShadowGeometry[4]
and curShadowGeometry[5]
and curShadowGeometry[6]
and curShadowGeometry[7]
and curShadowGeometry[8]
then
curShadowGeometry.alpha = body[i].alpha
curShadowGeometry.red = body[i].red
curShadowGeometry.green = body[i].green
curShadowGeometry.blue = body[i].blue
shadowGeometry[#shadowGeometry + 1] = curShadowGeometry
end
end
elseif body[i].shadowType == "circle" then
if not body[i].castsNoShadow then
local length = math.sqrt(math.pow(light.x - (body[i].x - body[i].ox), 2) + math.pow(light.y - (body[i].y - body[i].oy), 2))
if length >= body[i].radius and length <= light.range then
local curShadowGeometry = {}
local angle = math.atan2(light.x - (body[i].x - body[i].ox), (body[i].y - body[i].oy) - light.y) + math.pi / 2
local x2 = ((body[i].x - body[i].ox) + math.sin(angle) * body[i].radius)
local y2 = ((body[i].y - body[i].oy) - math.cos(angle) * body[i].radius)
local x3 = ((body[i].x - body[i].ox) - math.sin(angle) * body[i].radius)
local y3 = ((body[i].y - body[i].oy) + math.cos(angle) * body[i].radius)
curShadowGeometry[1] = x2
curShadowGeometry[2] = y2
curShadowGeometry[3] = x3
curShadowGeometry[4] = y3
curShadowGeometry[5] = x3 - (light.x - x3) * shadowLength
curShadowGeometry[6] = y3 - (light.y - y3) * shadowLength
curShadowGeometry[7] = x2 - (light.x - x2) * shadowLength
curShadowGeometry[8] = y2 - (light.y - y2) * shadowLength
curShadowGeometry.alpha = body[i].alpha
curShadowGeometry.red = body[i].red
curShadowGeometry.green = body[i].green
curShadowGeometry.blue = body[i].blue
shadowGeometry[#shadowGeometry + 1] = curShadowGeometry
end
end
end
end
return shadowGeometry
end
function HeightMapToNormalMap(heightMap, strength) function HeightMapToNormalMap(heightMap, strength)
local imgData = heightMap:getData() local imgData = heightMap:getData()
local imgData2 = love.image.newImageData(heightMap:getWidth(), heightMap:getHeight()) local imgData2 = love.image.newImageData(heightMap:getWidth(), heightMap:getHeight())