refactored into a normal map library which made body a bit smaller

This commit is contained in:
Tim Anema 2014-10-03 10:43:26 -04:00
parent ae7f8f7b80
commit b1c366e236
4 changed files with 131 additions and 119 deletions

View File

@ -1,6 +1,6 @@
local _PACKAGE = (...):match("^(.+)[%./][^%./]+") or "" local _PACKAGE = (...):match("^(.+)[%./][^%./]+") or ""
local class = require(_PACKAGE.."/class") local class = require(_PACKAGE.."/class")
local height_map_conv = require(_PACKAGE..'/height_map_conv') local normal_map = require(_PACKAGE..'/normal_map')
local vector = require(_PACKAGE..'/vector') local vector = require(_PACKAGE..'/vector')
local shadowLength = 100000 local shadowLength = 100000
@ -299,83 +299,22 @@ end
-- set height map -- set height map
function body:setHeightMap(heightMap, strength) function body:setHeightMap(heightMap, strength)
self:setNormalMap(height_map_conv.toNormalMap(heightMap, strength)) self:setNormalMap(normal_map.fromHeightMap(heightMap, strength))
end end
-- generate flat normal map -- generate flat normal map
function body:generateNormalMapFlat(mode) function body:generateNormalMapFlat(mode)
local imgData = self.img:getData() self:setNormalMap(normal_map.generateFlat(self.img, mode))
local imgNormalData = love.image.newImageData(self.imgWidth, self.imgHeight)
local color
if mode == "top" then
color = {127, 127, 255}
elseif mode == "front" then
color = {127, 0, 127}
elseif mode == "back" then
color = {127, 255, 127}
elseif mode == "left" then
color = {31, 0, 223}
elseif mode == "right" then
color = {223, 0, 127}
end
for i = 0, self.imgHeight - 1 do
for k = 0, self.imgWidth - 1 do
local r, g, b, a = imgData:getPixel(k, i)
if a > 0 then
imgNormalData:setPixel(k, i, color[1], color[2], color[3], 255)
end
end
end
self:setNormalMap(love.graphics.newImage(imgNormalData))
end end
-- generate faded normal map -- generate faded normal map
function body:generateNormalMapGradient(horizontalGradient, verticalGradient) function body:generateNormalMapGradient(horizontalGradient, verticalGradient)
local imgData = self.img:getData() self:setNormalMap(normal_map.generateGradient(self.img, horizontalGradient, verticalGradient))
local imgNormalData = love.image.newImageData(self.imgWidth, self.imgHeight)
local dx = 255.0 / self.imgWidth
local dy = 255.0 / self.imgHeight
local nx
local ny
local nz
for i = 0, self.imgWidth - 1 do
for k = 0, self.imgHeight - 1 do
local r, g, b, a = imgData:getPixel(i, k)
if a > 0 then
if horizontalGradient == "gradient" then
nx = i * dx
elseif horizontalGradient == "inverse" then
nx = 255 - i * dx
else
nx = 127
end
if verticalGradient == "gradient" then
ny = 127 - k * dy * 0.5
nz = 255 - k * dy * 0.5
elseif verticalGradient == "inverse" then
ny = 127 + k * dy * 0.5
nz = 127 - k * dy * 0.25
else
ny = 255
nz = 127
end
imgNormalData:setPixel(i, k, nx, ny, nz, 255)
end
end
end
self:setNormalMap(love.graphics.newImage(imgNormalData))
end end
-- generate normal map -- generate normal map
function body:generateNormalMap(strength) function body:generateNormalMap(strength)
self:setNormalMap(height_map_conv.toNormalMap(self.img, strength)) self:setNormalMap(normal_map.fromHeightMap(self.img, strength))
end end
-- set material -- set material

View File

@ -1,50 +0,0 @@
height_map = {}
function height_map.toNormalMap(heightMap, strength)
local imgData = heightMap:getData()
local imgData2 = love.image.newImageData(heightMap:getWidth(), heightMap:getHeight())
local red, green, blue, alpha
local x, y
local matrix = {}
matrix[1] = {}
matrix[2] = {}
matrix[3] = {}
strength = strength or 1.0
for i = 0, heightMap:getHeight() - 1 do
for k = 0, heightMap:getWidth() - 1 do
for l = 1, 3 do
for m = 1, 3 do
if k + (l - 1) < 1 then
x = heightMap:getWidth() - 1
elseif k + (l - 1) > heightMap:getWidth() - 1 then
x = 1
else
x = k + l - 1
end
if i + (m - 1) < 1 then
y = heightMap:getHeight() - 1
elseif i + (m - 1) > heightMap:getHeight() - 1 then
y = 1
else
y = i + m - 1
end
local red, green, blue, alpha = imgData:getPixel(x, y)
matrix[l][m] = red
end
end
red = (255 + ((matrix[1][2] - matrix[2][2]) + (matrix[2][2] - matrix[3][2])) * strength) / 2.0
green = (255 + ((matrix[2][2] - matrix[1][1]) + (matrix[2][3] - matrix[2][2])) * strength) / 2.0
blue = 192
imgData2:setPixel(k, i, red, green, blue)
end
end
return love.graphics.newImage(imgData2)
end
return height_map

View File

@ -25,7 +25,7 @@ local _PACKAGE = (...):match("^(.+)[%./][^%./]+") or ""
local class = require(_PACKAGE..'/class') local class = require(_PACKAGE..'/class')
local Light = require(_PACKAGE..'/light') local Light = require(_PACKAGE..'/light')
local Body = require(_PACKAGE..'/body') local Body = require(_PACKAGE..'/body')
local height_map_conv = require(_PACKAGE..'/height_map_conv') local normal_map = require(_PACKAGE..'/normal_map')
local light_world = class() local light_world = class()
@ -456,7 +456,7 @@ end
-- new refraction from height map -- new refraction from height map
function light_world:newRefractionHeightMap(heightMap, x, y, strength) function light_world:newRefractionHeightMap(heightMap, x, y, strength)
local normal = height_map_conv.toNormalMap(heightMap, strength) local normal = normal_map.fromHeightMap(heightMap, strength)
self.isRefraction = true self.isRefraction = true
return self.newRefraction(p, normal, x, y) return self.newRefraction(p, normal, x, y)
end end
@ -469,7 +469,7 @@ end
-- new reflection from height map -- new reflection from height map
function light_world:newReflectionHeightMap(heightMap, x, y, strength) function light_world:newReflectionHeightMap(heightMap, x, y, strength)
local normal = height_map_conv.toNormalMap(heightMap, strength) local normal = normal_map.fromHeightMap(heightMap, strength)
self.isReflection = true self.isReflection = true
return self.newReflection(p, normal, x, y) return self.newReflection(p, normal, x, y)
end end

123
lib/normal_map.lua Normal file
View File

@ -0,0 +1,123 @@
normal_map = {}
function normal_map.fromHeightMap(heightMap, strength)
local imgData = heightMap:getData()
local imgData2 = love.image.newImageData(heightMap:getWidth(), heightMap:getHeight())
local red, green, blue, alpha
local x, y
local matrix = {}
matrix[1] = {}
matrix[2] = {}
matrix[3] = {}
strength = strength or 1.0
for i = 0, heightMap:getHeight() - 1 do
for k = 0, heightMap:getWidth() - 1 do
for l = 1, 3 do
for m = 1, 3 do
if k + (l - 1) < 1 then
x = heightMap:getWidth() - 1
elseif k + (l - 1) > heightMap:getWidth() - 1 then
x = 1
else
x = k + l - 1
end
if i + (m - 1) < 1 then
y = heightMap:getHeight() - 1
elseif i + (m - 1) > heightMap:getHeight() - 1 then
y = 1
else
y = i + m - 1
end
local red, green, blue, alpha = imgData:getPixel(x, y)
matrix[l][m] = red
end
end
red = (255 + ((matrix[1][2] - matrix[2][2]) + (matrix[2][2] - matrix[3][2])) * strength) / 2.0
green = (255 + ((matrix[2][2] - matrix[1][1]) + (matrix[2][3] - matrix[2][2])) * strength) / 2.0
blue = 192
imgData2:setPixel(k, i, red, green, blue)
end
end
return love.graphics.newImage(imgData2)
end
function normal_map.generateFlat(img, mode)
local imgData = img:getData()
local imgNormalData = love.image.newImageData(img:getWidth(), img:getHeight())
local color
if mode == "top" then
color = {127, 127, 255}
elseif mode == "front" then
color = {127, 0, 127}
elseif mode == "back" then
color = {127, 255, 127}
elseif mode == "left" then
color = {31, 0, 223}
elseif mode == "right" then
color = {223, 0, 127}
end
for i = 0, self.imgHeight - 1 do
for k = 0, self.imgWidth - 1 do
local r, g, b, a = imgData:getPixel(k, i)
if a > 0 then
imgNormalData:setPixel(k, i, color[1], color[2], color[3], 255)
end
end
end
return love.graphics.newImage(imgNormalData)
end
function normal_map.generateGradient(img, horizontalGradient, verticalGradient)
horizontalGradient = horizontalGradient or "gradient"
verticalGradient = verticalGradient or horizontalGradient
local imgData = img:getData()
local imgWidth, imgHeight = img:getWidth(), img:getHeight()
local imgNormalData = love.image.newImageData(imgWidth, imgHeight)
local dx = 255.0 / imgWidth
local dy = 255.0 / imgHeight
local nx
local ny
local nz
for i = 0, imgWidth - 1 do
for k = 0, imgHeight - 1 do
local r, g, b, a = imgData:getPixel(i, k)
if a > 0 then
if horizontalGradient == "gradient" then
nx = i * dx
elseif horizontalGradient == "inverse" then
nx = 255 - i * dx
else
nx = 127
end
if verticalGradient == "gradient" then
ny = 127 - k * dy * 0.5
nz = 255 - k * dy * 0.5
elseif verticalGradient == "inverse" then
ny = 127 + k * dy * 0.5
nz = 127 - k * dy * 0.25
else
ny = 255
nz = 127
end
imgNormalData:setPixel(i, k, nx, ny, nz, 255)
end
end
end
return love.graphics.newImage(imgNormalData)
end
return normal_map