2014-09-26 16:48:46 +00:00
|
|
|
local _PACKAGE = (...):match("^(.+)[%./][^%./]+") or ""
|
|
|
|
local class = require(_PACKAGE.."/class")
|
2014-10-03 14:43:26 +00:00
|
|
|
local normal_map = require(_PACKAGE..'/normal_map')
|
2014-10-03 14:18:06 +00:00
|
|
|
local vector = require(_PACKAGE..'/vector')
|
|
|
|
local shadowLength = 100000
|
2014-09-26 16:48:46 +00:00
|
|
|
|
2014-09-26 20:52:16 +00:00
|
|
|
local body = class()
|
|
|
|
|
2014-09-29 14:03:15 +00:00
|
|
|
body.glowShader = love.graphics.newShader(_PACKAGE.."/shaders/glow.glsl")
|
|
|
|
body.materialShader = love.graphics.newShader(_PACKAGE.."/shaders/material.glsl")
|
|
|
|
|
2014-10-03 00:32:31 +00:00
|
|
|
function body:init(id, type, ...)
|
2014-09-26 16:48:46 +00:00
|
|
|
local args = {...}
|
2014-09-26 20:52:16 +00:00
|
|
|
self.id = id
|
|
|
|
self.type = type
|
2014-09-27 17:46:46 +00:00
|
|
|
self.shine = true
|
|
|
|
self.red = 0
|
|
|
|
self.green = 0
|
|
|
|
self.blue = 0
|
|
|
|
self.alpha = 1.0
|
|
|
|
self.glowRed = 255
|
|
|
|
self.glowGreen = 255
|
|
|
|
self.glowBlue = 255
|
|
|
|
self.glowStrength = 0.0
|
|
|
|
self.tileX = 0
|
|
|
|
self.tileY = 0
|
|
|
|
|
2014-09-26 20:52:16 +00:00
|
|
|
if self.type == "circle" then
|
|
|
|
self.x = args[1] or 0
|
|
|
|
self.y = args[2] or 0
|
2014-10-03 14:18:06 +00:00
|
|
|
self:setShadowType('circle', args[3], args[4], args[5])
|
2014-09-26 20:52:16 +00:00
|
|
|
elseif self.type == "rectangle" then
|
|
|
|
self.x = args[1] or 0
|
|
|
|
self.y = args[2] or 0
|
2014-10-03 14:18:06 +00:00
|
|
|
self:setShadowType('rectangle', args[3], args[4])
|
2014-09-26 20:52:16 +00:00
|
|
|
elseif self.type == "polygon" then
|
2014-10-03 14:18:06 +00:00
|
|
|
self:setShadowType('polygon', ...)
|
2014-09-26 20:52:16 +00:00
|
|
|
elseif self.type == "image" then
|
|
|
|
self.img = args[1]
|
|
|
|
self.x = args[2] or 0
|
|
|
|
self.y = args[3] or 0
|
|
|
|
if self.img then
|
|
|
|
self.imgWidth = self.img:getWidth()
|
|
|
|
self.imgHeight = self.img:getHeight()
|
|
|
|
self.ix = self.imgWidth * 0.5
|
|
|
|
self.iy = self.imgHeight * 0.5
|
2014-09-26 16:48:46 +00:00
|
|
|
end
|
2014-10-06 13:31:14 +00:00
|
|
|
self:setShadowType('rectangle', args[4] or self.imgWidth, args[5] or self.imgHeight, args[6], args[7])
|
2014-09-26 20:52:16 +00:00
|
|
|
self.reflective = true
|
|
|
|
elseif self.type == "refraction" then
|
2014-10-03 14:18:06 +00:00
|
|
|
self:initNormal(...)
|
2014-09-26 20:52:16 +00:00
|
|
|
self.refraction = true
|
|
|
|
elseif self.type == "reflection" then
|
2014-10-03 14:18:06 +00:00
|
|
|
self:initNormal(...)
|
2014-09-26 20:52:16 +00:00
|
|
|
self.reflection = true
|
2014-09-26 16:48:46 +00:00
|
|
|
end
|
2014-09-26 20:52:16 +00:00
|
|
|
end
|
2014-09-26 16:48:46 +00:00
|
|
|
|
2014-10-03 14:18:06 +00:00
|
|
|
function body:initNormal(...)
|
|
|
|
local args = {...}
|
|
|
|
self.normal = args[1]
|
|
|
|
self.x = args[2] or 0
|
|
|
|
self.y = args[3] or 0
|
|
|
|
if self.normal then
|
|
|
|
self.normalWidth = self.normal:getWidth()
|
|
|
|
self.normalHeight = self.normal:getHeight()
|
|
|
|
self.width = args[4] or self.normalWidth
|
|
|
|
self.height = args[5] or self.normalHeight
|
|
|
|
self.nx = self.normalWidth * 0.5
|
|
|
|
self.ny = self.normalHeight * 0.5
|
|
|
|
self.normal:setWrap("repeat", "repeat")
|
|
|
|
self.normalVert = {
|
|
|
|
{0.0, 0.0, 0.0, 0.0},
|
|
|
|
{self.width, 0.0, 1.0, 0.0},
|
|
|
|
{self.width, self.height, 1.0, 1.0},
|
|
|
|
{0.0, self.height, 0.0, 1.0}
|
|
|
|
}
|
|
|
|
self.normalMesh = love.graphics.newMesh(self.normalVert, self.normal, "fan")
|
|
|
|
else
|
|
|
|
self.width = args[4] or 64
|
|
|
|
self.height = args[5] or 64
|
|
|
|
end
|
|
|
|
self.ox = self.width * 0.5
|
|
|
|
self.oy = self.height * 0.5
|
|
|
|
end
|
|
|
|
|
2014-09-26 16:48:46 +00:00
|
|
|
-- refresh
|
|
|
|
function body:refresh()
|
2014-10-06 21:27:41 +00:00
|
|
|
if self.x and self.y and self.width and self.height and self.ox and self.oy then
|
|
|
|
self.data = {
|
|
|
|
self.x - self.ox,
|
|
|
|
self.y - self.oy,
|
|
|
|
self.x - self.ox + self.width,
|
|
|
|
self.y - self.oy,
|
|
|
|
self.x - self.ox + self.width,
|
|
|
|
self.y - self.oy + self.height,
|
|
|
|
self.x - self.ox,
|
|
|
|
self.y - self.oy + self.height
|
|
|
|
}
|
|
|
|
end
|
2014-09-26 16:48:46 +00:00
|
|
|
end
|
2014-09-27 19:58:15 +00:00
|
|
|
|
2014-09-26 16:48:46 +00:00
|
|
|
-- set position
|
|
|
|
function body:setPosition(x, y)
|
|
|
|
if x ~= self.x or y ~= self.y then
|
|
|
|
self.x = x
|
|
|
|
self.y = y
|
|
|
|
self:refresh()
|
|
|
|
end
|
|
|
|
end
|
2014-09-27 19:58:15 +00:00
|
|
|
|
2014-09-26 16:48:46 +00:00
|
|
|
-- get x position
|
2014-10-26 19:35:53 +00:00
|
|
|
function body:getPosition()
|
|
|
|
return self.x, self.y
|
2014-09-26 16:48:46 +00:00
|
|
|
end
|
2014-09-27 19:58:15 +00:00
|
|
|
|
2014-09-26 16:48:46 +00:00
|
|
|
-- get width
|
|
|
|
function body:getWidth()
|
|
|
|
return self.width
|
|
|
|
end
|
2014-09-27 19:58:15 +00:00
|
|
|
|
2014-09-26 16:48:46 +00:00
|
|
|
-- get height
|
|
|
|
function body:getHeight()
|
|
|
|
return self.height
|
|
|
|
end
|
2014-09-27 19:58:15 +00:00
|
|
|
|
2014-09-26 16:48:46 +00:00
|
|
|
-- get image width
|
|
|
|
function body:getImageWidth()
|
|
|
|
return self.imgWidth
|
|
|
|
end
|
2014-09-27 19:58:15 +00:00
|
|
|
|
2014-09-26 16:48:46 +00:00
|
|
|
-- get image height
|
|
|
|
function body:getImageHeight()
|
|
|
|
return self.imgHeight
|
|
|
|
end
|
2014-09-27 19:58:15 +00:00
|
|
|
|
2014-09-26 16:48:46 +00:00
|
|
|
-- set dimension
|
|
|
|
function body:setDimension(width, height)
|
|
|
|
self.width = width
|
|
|
|
self.height = height
|
|
|
|
self:refresh()
|
|
|
|
end
|
2014-09-27 19:58:15 +00:00
|
|
|
|
2014-09-26 16:48:46 +00:00
|
|
|
-- set offset
|
|
|
|
function body:setOffset(ox, oy)
|
|
|
|
if ox ~= self.ox or oy ~= self.oy then
|
|
|
|
self.ox = ox
|
|
|
|
self.oy = oy
|
2014-10-06 21:27:41 +00:00
|
|
|
self:refresh()
|
2014-09-26 16:48:46 +00:00
|
|
|
end
|
|
|
|
end
|
2014-09-27 19:58:15 +00:00
|
|
|
|
2014-09-26 16:48:46 +00:00
|
|
|
-- set offset
|
|
|
|
function body:setImageOffset(ix, iy)
|
|
|
|
if ix ~= self.ix or iy ~= self.iy then
|
|
|
|
self.ix = ix
|
|
|
|
self.iy = iy
|
|
|
|
self:refresh()
|
|
|
|
end
|
|
|
|
end
|
2014-09-27 19:58:15 +00:00
|
|
|
|
2014-09-26 16:48:46 +00:00
|
|
|
-- set offset
|
|
|
|
function body:setNormalOffset(nx, ny)
|
|
|
|
if nx ~= self.nx or ny ~= self.ny then
|
|
|
|
self.nx = nx
|
|
|
|
self.ny = ny
|
|
|
|
self:refresh()
|
|
|
|
end
|
|
|
|
end
|
2014-09-27 19:58:15 +00:00
|
|
|
|
2014-09-26 16:48:46 +00:00
|
|
|
-- set glow color
|
|
|
|
function body:setGlowColor(red, green, blue)
|
|
|
|
self.glowRed = red
|
|
|
|
self.glowGreen = green
|
|
|
|
self.glowBlue = blue
|
|
|
|
end
|
2014-09-27 19:58:15 +00:00
|
|
|
|
2014-09-26 16:48:46 +00:00
|
|
|
-- set glow alpha
|
|
|
|
function body:setGlowStrength(strength)
|
|
|
|
self.glowStrength = strength
|
|
|
|
end
|
2014-09-27 19:58:15 +00:00
|
|
|
|
2014-09-26 16:48:46 +00:00
|
|
|
-- get radius
|
|
|
|
function body:getRadius()
|
|
|
|
return self.radius
|
|
|
|
end
|
2014-09-27 19:58:15 +00:00
|
|
|
|
2014-09-26 16:48:46 +00:00
|
|
|
-- set radius
|
|
|
|
function body:setRadius(radius)
|
|
|
|
if radius ~= self.radius then
|
|
|
|
self.radius = radius
|
|
|
|
end
|
|
|
|
end
|
2014-09-27 19:58:15 +00:00
|
|
|
|
2014-09-26 16:48:46 +00:00
|
|
|
-- set polygon data
|
|
|
|
function body:setPoints(...)
|
|
|
|
self.data = {...}
|
|
|
|
end
|
2014-09-27 19:58:15 +00:00
|
|
|
|
2014-09-26 16:48:46 +00:00
|
|
|
-- get polygon data
|
|
|
|
function body:getPoints()
|
|
|
|
return unpack(self.data)
|
|
|
|
end
|
2014-09-27 19:58:15 +00:00
|
|
|
|
2014-09-26 16:48:46 +00:00
|
|
|
-- set shadow on/off
|
|
|
|
function body:setShadow(b)
|
|
|
|
self.castsNoShadow = not b
|
|
|
|
end
|
2014-09-27 19:58:15 +00:00
|
|
|
|
2014-09-26 16:48:46 +00:00
|
|
|
-- set shine on/off
|
|
|
|
function body:setShine(b)
|
|
|
|
self.shine = b
|
|
|
|
end
|
2014-09-27 19:58:15 +00:00
|
|
|
|
2014-09-26 16:48:46 +00:00
|
|
|
-- set glass color
|
|
|
|
function body:setColor(red, green, blue)
|
|
|
|
self.red = red
|
|
|
|
self.green = green
|
|
|
|
self.blue = blue
|
|
|
|
end
|
2014-09-27 19:58:15 +00:00
|
|
|
|
2014-09-26 16:48:46 +00:00
|
|
|
-- set glass alpha
|
|
|
|
function body:setAlpha(alpha)
|
|
|
|
self.alpha = alpha
|
|
|
|
end
|
2014-09-27 19:58:15 +00:00
|
|
|
|
2014-09-26 16:48:46 +00:00
|
|
|
-- set reflection on/off
|
|
|
|
function body:setReflection(reflection)
|
|
|
|
self.reflection = reflection
|
|
|
|
end
|
2014-09-27 19:58:15 +00:00
|
|
|
|
2014-09-26 16:48:46 +00:00
|
|
|
-- set refraction on/off
|
|
|
|
function body:setRefraction(refraction)
|
|
|
|
self.refraction = refraction
|
|
|
|
end
|
2014-09-27 19:58:15 +00:00
|
|
|
|
2014-09-26 16:48:46 +00:00
|
|
|
-- set reflective on other objects on/off
|
|
|
|
function body:setReflective(reflective)
|
|
|
|
self.reflective = reflective
|
|
|
|
end
|
2014-09-27 19:58:15 +00:00
|
|
|
|
2014-09-26 16:48:46 +00:00
|
|
|
-- set refractive on other objects on/off
|
|
|
|
function body:setRefractive(refractive)
|
|
|
|
self.refractive = refractive
|
|
|
|
end
|
2014-09-27 19:58:15 +00:00
|
|
|
|
2014-09-26 16:48:46 +00:00
|
|
|
-- set image
|
|
|
|
function body:setImage(img)
|
|
|
|
if img then
|
|
|
|
self.img = img
|
|
|
|
self.imgWidth = self.img:getWidth()
|
|
|
|
self.imgHeight = self.img:getHeight()
|
|
|
|
self.ix = self.imgWidth * 0.5
|
|
|
|
self.iy = self.imgHeight * 0.5
|
|
|
|
end
|
|
|
|
end
|
2014-09-27 19:58:15 +00:00
|
|
|
|
2014-09-26 16:48:46 +00:00
|
|
|
-- set normal
|
|
|
|
function body:setNormalMap(normal, width, height, nx, ny)
|
|
|
|
if normal then
|
|
|
|
self.normal = normal
|
|
|
|
self.normal:setWrap("repeat", "repeat")
|
|
|
|
self.normalWidth = width or self.normal:getWidth()
|
|
|
|
self.normalHeight = height or self.normal:getHeight()
|
|
|
|
self.nx = nx or self.normalWidth * 0.5
|
|
|
|
self.ny = ny or self.normalHeight * 0.5
|
|
|
|
self.normalVert = {
|
|
|
|
{0.0, 0.0, 0.0, 0.0},
|
|
|
|
{self.normalWidth, 0.0, self.normalWidth / self.normal:getWidth(), 0.0},
|
|
|
|
{self.normalWidth, self.normalHeight, self.normalWidth / self.normal:getWidth(), self.normalHeight / self.normal:getHeight()},
|
|
|
|
{0.0, self.normalHeight, 0.0, self.normalHeight / self.normal:getHeight()}
|
|
|
|
}
|
|
|
|
self.normalMesh = love.graphics.newMesh(self.normalVert, self.normal, "fan")
|
|
|
|
else
|
|
|
|
self.normalMesh = nil
|
|
|
|
end
|
|
|
|
end
|
2014-09-27 19:58:15 +00:00
|
|
|
|
2014-09-26 16:48:46 +00:00
|
|
|
-- set height map
|
|
|
|
function body:setHeightMap(heightMap, strength)
|
2014-10-03 14:43:26 +00:00
|
|
|
self:setNormalMap(normal_map.fromHeightMap(heightMap, strength))
|
2014-09-26 16:48:46 +00:00
|
|
|
end
|
2014-09-27 19:58:15 +00:00
|
|
|
|
2014-09-26 16:48:46 +00:00
|
|
|
-- generate flat normal map
|
|
|
|
function body:generateNormalMapFlat(mode)
|
2014-10-03 14:43:26 +00:00
|
|
|
self:setNormalMap(normal_map.generateFlat(self.img, mode))
|
2014-09-26 16:48:46 +00:00
|
|
|
end
|
2014-09-27 19:58:15 +00:00
|
|
|
|
2014-09-26 16:48:46 +00:00
|
|
|
-- generate faded normal map
|
|
|
|
function body:generateNormalMapGradient(horizontalGradient, verticalGradient)
|
2014-10-03 14:43:26 +00:00
|
|
|
self:setNormalMap(normal_map.generateGradient(self.img, horizontalGradient, verticalGradient))
|
2014-09-26 16:48:46 +00:00
|
|
|
end
|
2014-09-27 19:58:15 +00:00
|
|
|
|
2014-09-26 16:48:46 +00:00
|
|
|
-- generate normal map
|
|
|
|
function body:generateNormalMap(strength)
|
2014-10-03 14:43:26 +00:00
|
|
|
self:setNormalMap(normal_map.fromHeightMap(self.img, strength))
|
2014-09-26 16:48:46 +00:00
|
|
|
end
|
2014-09-27 17:46:46 +00:00
|
|
|
|
2014-09-26 16:48:46 +00:00
|
|
|
-- set material
|
|
|
|
function body:setMaterial(material)
|
|
|
|
if material then
|
|
|
|
self.material = material
|
|
|
|
end
|
|
|
|
end
|
2014-09-27 17:46:46 +00:00
|
|
|
|
2014-09-26 16:48:46 +00:00
|
|
|
-- set normal
|
|
|
|
function body:setGlowMap(glow)
|
|
|
|
self.glow = glow
|
|
|
|
self.glowStrength = 1.0
|
|
|
|
end
|
2014-09-27 17:46:46 +00:00
|
|
|
|
2014-09-26 16:48:46 +00:00
|
|
|
-- set tile offset
|
|
|
|
function body:setNormalTileOffset(tx, ty)
|
|
|
|
self.tileX = tx / self.normalWidth
|
|
|
|
self.tileY = ty / self.normalHeight
|
|
|
|
self.normalVert = {
|
|
|
|
{0.0, 0.0, self.tileX, self.tileY},
|
|
|
|
{self.normalWidth, 0.0, self.tileX + 1.0, self.tileY},
|
|
|
|
{self.normalWidth, self.normalHeight, self.tileX + 1.0, self.tileY + 1.0},
|
|
|
|
{0.0, self.normalHeight, self.tileX, self.tileY + 1.0}
|
|
|
|
}
|
|
|
|
end
|
2014-09-27 17:46:46 +00:00
|
|
|
|
2014-09-26 16:48:46 +00:00
|
|
|
-- get type
|
|
|
|
function body:getType()
|
|
|
|
return self.type
|
|
|
|
end
|
2014-09-27 17:46:46 +00:00
|
|
|
|
2014-09-26 16:48:46 +00:00
|
|
|
-- get type
|
|
|
|
function body:setShadowType(type, ...)
|
|
|
|
self.shadowType = type
|
|
|
|
local args = {...}
|
|
|
|
if self.shadowType == "circle" then
|
|
|
|
self.radius = args[1] or 16
|
|
|
|
self.ox = args[2] or 0
|
|
|
|
self.oy = args[3] or 0
|
|
|
|
elseif self.shadowType == "rectangle" then
|
|
|
|
self.width = args[1] or 64
|
|
|
|
self.height = args[2] or 64
|
|
|
|
self.ox = args[3] or self.width * 0.5
|
|
|
|
self.oy = args[4] or self.height * 0.5
|
2014-10-03 14:18:06 +00:00
|
|
|
self:refresh()
|
2014-09-26 16:48:46 +00:00
|
|
|
elseif self.shadowType == "polygon" then
|
|
|
|
self.data = args or {0, 0, 0, 0, 0, 0}
|
|
|
|
elseif self.shadowType == "image" then
|
|
|
|
if self.img then
|
|
|
|
self.width = self.imgWidth
|
|
|
|
self.height = self.imgHeight
|
|
|
|
self.shadowVert = {
|
|
|
|
{0.0, 0.0, 0.0, 0.0},
|
|
|
|
{self.width, 0.0, 1.0, 0.0},
|
|
|
|
{self.width, self.height, 1.0, 1.0},
|
|
|
|
{0.0, self.height, 0.0, 1.0}
|
|
|
|
}
|
|
|
|
if not self.shadowMesh then
|
|
|
|
self.shadowMesh = love.graphics.newMesh(self.shadowVert, self.img, "fan")
|
|
|
|
self.shadowMesh:setVertexColors(true)
|
|
|
|
end
|
|
|
|
else
|
|
|
|
self.width = 64
|
|
|
|
self.height = 64
|
|
|
|
end
|
|
|
|
self.shadowX = args[1] or 0
|
|
|
|
self.shadowY = args[2] or 0
|
|
|
|
self.fadeStrength = args[3] or 0.0
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2014-10-24 02:41:52 +00:00
|
|
|
function body:stencil()
|
2014-10-22 02:48:19 +00:00
|
|
|
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))
|
|
|
|
elseif self.shadowType == "image" then
|
|
|
|
--love.graphics.rectangle("fill", self.x - self.ox, self.y - self.oy, self.width, self.height)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2014-10-23 12:25:12 +00:00
|
|
|
function body:drawShadow(light)
|
2014-09-26 22:11:23 +00:00
|
|
|
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 = {
|
2014-10-03 03:04:22 +00:00
|
|
|
{
|
|
|
|
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
|
|
|
|
}
|
2014-09-26 22:11:23 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
self.shadowMesh:setVertices(self.shadowVert)
|
2014-10-23 12:25:12 +00:00
|
|
|
love.graphics.draw(self.shadowMesh, self.x - self.ox, self.y - self.oy, 0, s, s)
|
2014-09-26 22:11:23 +00:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2014-10-23 12:25:12 +00:00
|
|
|
function body:drawPixelShadow()
|
2014-09-26 22:11:23 +00:00
|
|
|
if self.type == "image" and self.normalMesh then
|
|
|
|
love.graphics.setColor(255, 255, 255)
|
2014-09-30 22:19:37 +00:00
|
|
|
love.graphics.draw(self.normalMesh, self.x - self.nx, self.y - self.ny)
|
2014-09-26 22:11:23 +00:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2014-10-23 12:25:12 +00:00
|
|
|
function body:drawGlow()
|
2014-09-26 22:11:23 +00:00
|
|
|
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
|
2014-09-29 14:03:15 +00:00
|
|
|
love.graphics.setShader(self.glowShader)
|
|
|
|
self.glowShader:send("glowImage", self.glow)
|
|
|
|
self.glowShader:send("glowTime", love.timer.getTime() * 0.5)
|
2014-09-26 22:11:23 +00:00
|
|
|
love.graphics.setColor(255, 255, 255)
|
|
|
|
else
|
|
|
|
love.graphics.setShader()
|
|
|
|
love.graphics.setColor(0, 0, 0)
|
|
|
|
end
|
2014-09-30 22:19:37 +00:00
|
|
|
love.graphics.draw(self.img, self.x - self.ix, self.y - self.iy)
|
2014-09-26 22:11:23 +00:00
|
|
|
end
|
2014-09-27 21:18:54 +00:00
|
|
|
|
|
|
|
love.graphics.setShader()
|
2014-09-26 22:11:23 +00:00
|
|
|
end
|
|
|
|
|
2014-10-23 12:25:12 +00:00
|
|
|
function body:drawRefraction()
|
2014-09-26 22:11:23 +00:00
|
|
|
if self.refraction and self.normal then
|
|
|
|
love.graphics.setColor(255, 255, 255)
|
|
|
|
if self.tileX == 0.0 and self.tileY == 0.0 then
|
2014-10-23 12:25:12 +00:00
|
|
|
love.graphics.draw(normal, self.x - self.nx, self.y - self.ny)
|
2014-09-26 22:11:23 +00:00
|
|
|
else
|
|
|
|
self.normalMesh:setVertices(self.normalVert)
|
2014-10-23 12:25:12 +00:00
|
|
|
love.graphics.draw(self.normalMesh, self.x - self.nx, self.y - self.ny)
|
2014-09-26 22:11:23 +00:00
|
|
|
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
|
2014-10-23 12:25:12 +00:00
|
|
|
love.graphics.draw(self.img, self.x - self.ix, self.y - self.iy)
|
2014-09-26 22:11:23 +00:00
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2014-10-23 12:25:12 +00:00
|
|
|
function body:drawReflection()
|
2014-09-26 22:11:23 +00:00
|
|
|
if self.reflection and self.normal then
|
|
|
|
love.graphics.setColor(255, 0, 0)
|
|
|
|
self.normalMesh:setVertices(self.normalVert)
|
2014-10-23 12:25:12 +00:00
|
|
|
love.graphics.draw(self.normalMesh, self.x - self.nx, self.y - self.ny)
|
2014-09-26 22:11:23 +00:00
|
|
|
end
|
|
|
|
if self.reflective and self.img then
|
|
|
|
love.graphics.setColor(0, 255, 0)
|
2014-10-23 12:25:12 +00:00
|
|
|
love.graphics.draw(self.img, self.x - self.ix, self.y - self.iy)
|
2014-09-26 22:11:23 +00:00
|
|
|
elseif not self.reflection and self.img then
|
|
|
|
love.graphics.setColor(0, 0, 0)
|
2014-10-23 12:25:12 +00:00
|
|
|
love.graphics.draw(self.img, self.x - self.ix, self.y - self.iy)
|
2014-09-26 22:11:23 +00:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2014-10-23 12:25:12 +00:00
|
|
|
function body:drawMaterial()
|
2014-09-26 22:11:23 +00:00
|
|
|
if self.material and self.normal then
|
2014-09-29 14:03:15 +00:00
|
|
|
love.graphics.setShader(self.materialShader)
|
2014-09-26 22:11:23 +00:00
|
|
|
love.graphics.setColor(255, 255, 255)
|
2014-09-29 14:03:15 +00:00
|
|
|
self.materialShader:send("material", self.material)
|
2014-10-23 12:25:12 +00:00
|
|
|
love.graphics.draw(self.normal, self.x - self.nx, self.y - self.ny)
|
2014-09-29 14:03:15 +00:00
|
|
|
love.graphics.setShader()
|
2014-09-26 22:11:23 +00:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2014-10-03 14:18:06 +00:00
|
|
|
function body:calculateShadow(light)
|
|
|
|
if self.shadowType == "rectangle" or self.shadowType == "polygon" then
|
|
|
|
return self:calculatePolyShadow(light)
|
|
|
|
elseif self.shadowType == "circle" then
|
|
|
|
return self:calculateCircleShadow(light)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
function body:calculatePolyShadow(light)
|
|
|
|
if self.castsNoShadow then
|
|
|
|
return nil
|
|
|
|
end
|
|
|
|
|
|
|
|
local curPolygon = self.data
|
|
|
|
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 = self.alpha
|
|
|
|
curShadowGeometry.red = self.red
|
|
|
|
curShadowGeometry.green = self.green
|
|
|
|
curShadowGeometry.blue = self.blue
|
|
|
|
return curShadowGeometry
|
|
|
|
else
|
|
|
|
return nil
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
function body:calculateCircleShadow(light)
|
|
|
|
if self.castsNoShadow then
|
|
|
|
return nil
|
|
|
|
end
|
|
|
|
local length = math.sqrt(math.pow(light.x - (self.x - self.ox), 2) + math.pow(light.y - (self.y - self.oy), 2))
|
|
|
|
if length >= self.radius and length <= light.range then
|
|
|
|
local curShadowGeometry = {}
|
|
|
|
local angle = math.atan2(light.x - (self.x - self.ox), (self.y - self.oy) - light.y) + math.pi / 2
|
|
|
|
local x2 = ((self.x - self.ox) + math.sin(angle) * self.radius)
|
|
|
|
local y2 = ((self.y - self.oy) - math.cos(angle) * self.radius)
|
|
|
|
local x3 = ((self.x - self.ox) - math.sin(angle) * self.radius)
|
|
|
|
local y3 = ((self.y - self.oy) + math.cos(angle) * self.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 = self.alpha
|
|
|
|
curShadowGeometry.red = self.red
|
|
|
|
curShadowGeometry.green = self.green
|
|
|
|
curShadowGeometry.blue = self.blue
|
|
|
|
return curShadowGeometry
|
|
|
|
else
|
|
|
|
return nil
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2014-09-26 16:48:46 +00:00
|
|
|
return body
|