Add LDoc documentation. Utils done.

This commit is contained in:
Colby Klein 2015-09-11 07:59:05 -07:00
parent edbf08005d
commit 78989682cf
17 changed files with 243 additions and 124 deletions

View File

@ -2,5 +2,14 @@
"cmd": "busted",
"args": [ "spec" ],
"sh": false,
"cwd": "{PROJECT_PATH}"
"targets": {
"LDoc": {
"cmd": "ldoc",
"args": ["-c doc/config.ld", "-o index", "."]
},
"View Docs": {
"cmd": "xdg-open",
"args": ["doc/doc/index.html"]
}
}
}

2
.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
# LDoc generated files.
doc/doc

9
doc/config.ld Normal file
View File

@ -0,0 +1,9 @@
project="CPML"
title="CPML documentation"
description="A math library with (hopefully) everything you need for 2D/3D games"
format="markdown"
backtick_references=false
file = {
"../init.lua",
"../modules"
}

View File

@ -1,4 +1,10 @@
--[[
-------------------------------------------------------------------------------
-- @author Colby Klein
-- @author Landon Manning
-- @copyright 2015
-- @license MIT/X11
-------------------------------------------------------------------------------
.'@@@@@@@@@@@@@@#:
,@@@@#; .'@@@@+
,@@@' .@@@#

View File

@ -1,3 +1,6 @@
--- Color utilities
-- @module color
local current_folder = (...):gsub('%.[^%.]+$', '') .. "."
local utils = require(current_folder .. "utils")
local color = {}

View File

@ -1,3 +1,5 @@
-- @module constants
local constants = {}
-- same as C's FLT_EPSILON

View File

@ -1,3 +1,6 @@
--- Various geometric intersections
-- @module intersect
local current_folder = (...):gsub('%.[^%.]+$', '') .. "."
local vec3 = require(current_folder .. "vec3")
local constants = require(current_folder .. "constants")

View File

@ -1,3 +1,6 @@
--- 4x4 matrices
-- @module mat4
-- double 4x4, 1-based, column major
-- local matrix = {}

View File

@ -1,3 +1,6 @@
--- Mesh utilities
-- @module mesh
local current_folder = (...):gsub('%.[^%.]+$', '') .. "."
local vec3 = require(current_folder .. "vec3")

View File

@ -1,3 +1,6 @@
--- Octrees
-- @module octree
-- based on a gist from mentlerd
-- https://gist.github.com/mentlerd/4587030
local octree = {}
@ -10,10 +13,10 @@ octree.__index = octree
-- TODO: ability to store tables would be nice!
local function new()
local t = {
local t = {
root = {
size = 1,
size = 1,
x = 0,
y = 0,
z = 0
@ -28,43 +31,43 @@ function octree:expand_if_needed(x, y, z)
local root = self.root
local size = root.size
-- Relative coordinates
local rX = x - root.x
local rY = y - root.y
local rZ = z - root.z
-- Out of bounds marks
local xPos = rX >= size
local xNeg = rX < -size
local yPos = rY >= size
local yNeg = rY < -size
local zPos = rZ >= size
local zNeg = rZ < -size
-- Check if the point is in the bounds
if xPos or xNeg or
yPos or yNeg or
zPos or zNeg then
-- Change the root node to fit
local node = {
size = size * 2,
x = 0,
y = 0,
z = 0
}
local index = 0
-- Offset the new root, and place the old into it
if rX >= 0 then node.x = root.x + size end
if rY >= 0 then node.y = root.y + size end
if rZ >= 0 then node.z = root.z + size end
if rX < 0 then
node.x = root.x - size
index = index + 1
@ -85,10 +88,10 @@ function octree:expand_if_needed(x, y, z)
root.x = nil
root.y = nil
root.z = nil
-- Set the new root
self.root = node
-- Repeat until the size is sufficient
self:expand_if_needed(x, y, z)
end
@ -96,49 +99,49 @@ end
function octree:get(x, y, z)
self:expand_if_needed(x, y, z)
-- Convert the coordinates relative to the root
local node = self.root
local size = node.size
local rX = x - node.x
local rY = y - node.y
local rZ = z - node.z
while true do
size = size / 2
local index = 0
-- Seek, and offset the point for the next node
if rX >= 0 then
if rX >= 0 then
index = index + 1
rX = rX - size
rX = rX - size
else
rX = rX + size
end
if rY >= 0 then
index = index + 2
index = index + 2
rY = rY - size
else
rY = rY + size
end
if rZ >= 0 then
index = index + 4
rZ = rZ - size
if rZ >= 0 then
index = index + 4
rZ = rZ - size
else
rZ = rZ + size
end
-- Get the node/value at the calculated index
local child = node[index]
if type(child) ~= "table" then
if type(child) ~= "table" then
return child
end
-- We must go deeper!
node = child
end
@ -148,15 +151,15 @@ local function merge_if_possible(stack, path, ref)
for i = #stack, 1, -1 do
local node = stack[i]
-- Check if every value is the same in the node
-- Check if every value is the same in the node
for x = 0, 7, 1 do
if ref ~= node[x] then
-- Break if any is not
return
end
end
-- Successful merge
stack[i -1][path[i]] = ref
end
@ -165,24 +168,24 @@ end
function octree:set(x, y, z, value)
self:expand_if_needed(x, y, z)
-- Convert the coordinates relative to the root
local node = self.root
local size = node.size
local rX = x - node.x
local rY = y - node.y
local rZ = z - node.z
local stack = {}
local path = {}
while true do
while true do
size = size / 2
local index = 0
if rX >= 0 then
if rX >= 0 then
index = index + 1
rX = rX - size
else
@ -190,55 +193,55 @@ function octree:set(x, y, z, value)
end
if rY >= 0 then
index = index + 2
index = index + 2
rY = rY - size
else
rY = rY + size
end
if rZ >= 0 then
if rZ >= 0 then
index = index + 4
rZ = rZ - size
else
rZ = rZ + size
end
table.insert(stack, node)
table.insert(path, index)
-- Get the node/value at the calculated index
local child = node[index]
if type(child) ~= "table" then
if (child ~= value) then
-- No node/value present
if child == nil then
-- If the size is not 1, it needs further populating,
-- Otherwise, it just needs a value
if size ~= 0.5 then
if size ~= 0.5 then
child = {}
node[index] = child
else
else
node[index] = value
merge_if_possible(stack, path, value)
return
end
else
-- There is a node, but its value does not match, divide it
-- If the size is over 1, otherwise, just set the value
if size ~= 0.5 then
if size ~= 0.5 then
local split = {
child, child, child, child,
child, child, child, child,
child, child, child, child
}
child = split
node[index] = split
else
else
-- Hit a real leaf, set the value and walk away
node[index] = value
merge_if_possible(stack, path, value)
return
end
@ -248,7 +251,7 @@ function octree:set(x, y, z, value)
return
end
end
node = child
end
end

View File

@ -1,3 +1,6 @@
--- Quadtrees
-- @module quadtree
-- based on a gist from mentlerd
-- https://gist.github.com/mentlerd/4587030
local quadtree = {}
@ -5,10 +8,10 @@ local quadtree = {}
quadtree.__index = quadtree
local function new()
local t = {
local t = {
root = {
size = 1,
size = 1,
x = 0,
y = 0,
}
@ -22,36 +25,36 @@ function quadtree:expand_if_needed(x, y)
local root = self.root
local size = root.size
-- Relative coordinates
local rX = x - root.x
local rY = y - root.y
-- Out of bounds marks
local xPos = rX >= size
local xNeg = rX < -size
local yPos = rY >= size
local yNeg = rY < -size
-- Check if the point is in the bounds
if xPos or xNeg or
yPos or yNeg then
-- Change the root node to fit
local node = {
size = size * 2,
x = 0,
y = 0,
}
local index = 0
-- Offset the new root, and place the old into it
if rX >= 0 then node.x = root.x + size end
if rY >= 0 then node.y = root.y + size end
if rX < 0 then
node.x = root.x - size
index = index + 1
@ -67,10 +70,10 @@ function quadtree:expand_if_needed(x, y)
root.size = nil
root.x = nil
root.y = nil
-- Set the new root
self.root = node
-- Repeat until the size is sufficient
self:expand_if_needed(x, y)
end
@ -78,41 +81,41 @@ end
function quadtree:get(x, y)
self:expand_if_needed(x, y)
-- Convert the coordinates relative to the root
local node = self.root
local size = node.size
local rX = x - node.x
local rY = y - node.y
while true do
size = size / 2
local index = 0
-- Seek, and offset the point for the next node
if rX >= 0 then
if rX >= 0 then
index = index + 1
rX = rX - size
rX = rX - size
else
rX = rX + size
end
if rY >= 0 then
index = index + 2
index = index + 2
rY = rY - size
else
rY = rY + size
end
-- Get the node/value at the calculated index
local child = node[index]
if type(child) ~= "table" then
return child
end
-- We must go deeper!
node = child
end
@ -122,37 +125,37 @@ function quadtree:set(x, y, value)
local function merge_if_possible(stack, path, ref)
for i = #stack, 1, -1 do
local node = stack[i]
-- Check if every value is the same in the node
-- Check if every value is the same in the node
for x = 0, 7, 1 do
if ref ~= node[x] then
-- Break if any is not
return
end
end
-- Successful merge
stack[i -1][path[i]] = ref
end
end
self:expand_if_needed(x, y)
-- Convert the coordinates relative to the root
local node = self.root
local size = node.size
local rX = x - node.x
local rY = y - node.y
local stack = {}
local path = {}
while true do
while true do
size = size / 2
local index = 0
if rX >= 0 then
index = index + 1
rX = rX - size
@ -161,47 +164,47 @@ function quadtree:set(x, y, value)
end
if rY >= 0 then
index = index + 2
index = index + 2
rY = rY - size
else
rY = rY + size
end
table.insert(stack, node)
table.insert(path, index)
-- Get the node/value at the calculated index
local child = node[index]
if type(child) ~= "table" then
if (child ~= value) then
-- No node/value present
if child == nil then
-- If the size is not 1, it needs further populating,
-- Otherwise, it just needs a value
if size ~= 0.5 then
if size ~= 0.5 then
child = {}
node[index] = child
else
else
node[index] = value
merge_if_possible(stack, path, value)
return
end
else
-- There is a node, but its value does not match, divide it
-- If the size is over 1, otherwise, just set the value
if size ~= 0.5 then
if size ~= 0.5 then
local split = {
child, child, child, child
}
child = split
node[index] = split
else
else
-- Hit a real leaf, set the value and walk away
node[index] = value
merge_if_possible(stack, path, value)
return
end
@ -211,7 +214,7 @@ function quadtree:set(x, y, value)
return
end
end
node = child
end
end

View File

@ -1,5 +1,9 @@
--- Quaternions
-- @module quat
-- @alias quaternion
-- quaternions
-- Author: Andrew Stacey
-- @author Andrew Stacey
-- Website: http://www.math.ntnu.no/~stacey/HowDidIDoThat/iPad/Codea.html
-- Licence: CC0 http://wiki.creativecommons.org/CC0

View File

@ -1,3 +1,6 @@
--- Simplex Noise
-- @module simplex
--
-- Based on code in "Simplex noise demystified", by Stefan Gustavson
-- www.itn.liu.se/~stegu/simplexnoise/simplexnoise.pdf
@ -280,7 +283,7 @@ do
function M.Simplex4D (x, y, z, w)
--[[
4D skew factors:
F = (math.sqrt(5) - 1) / 4
F = (math.sqrt(5) - 1) / 4
G = (5 - math.sqrt(5)) / 20
G2 = 2 * G
G3 = 3 * G
@ -352,4 +355,4 @@ do
end
-- Export the module.
return M
return M

View File

@ -1,3 +1,6 @@
--- Various utility functions
-- @module utils
local utils = {}
-- reimplementation of math.frexp, due to its removal from Lua 5.3 :(
@ -10,48 +13,95 @@ local frexp = math.frexp or function(x)
return x / 2 ^ e, e
end
function utils.clamp(v, min, max)
return math.max(math.min(v, max), min)
--- Clamps a value within the specified range.
-- @param value Input value
-- @param min Minimum output value
-- @param max Maximum output value
-- @return number
function utils.clamp(value, min, max)
return math.max(math.min(value, max), min)
end
--- Returns `value` if it is equal or greater than |`size`|, or 0.
-- @param value
-- @param size
-- @return number
function utils.deadzone(value, size)
return math.abs(value) >= size and value or 0
end
-- I know, it barely saves any typing at all.
--- Check if value is equal or greater than threshold.
-- @param value
-- @param threshold
-- @return boolean
function utils.threshold(value, threshold)
-- I know, it barely saves any typing at all.
return math.abs(value) >= threshold
end
function utils.map(v, min_in, max_in, min_out, max_out)
return ((v) - (min_in)) * ((max_out) - (min_out)) / ((max_in) - (min_in)) + (min_out)
--- Scales a value from one range to another.
-- @param value Input value
-- @param min_in Minimum input value
-- @param max_in Maximum input value
-- @param min_out Minimum output value
-- @param max_out Maximum output value
-- @return number
function utils.map(value, min_in, max_in, min_out, max_out)
return ((value) - (min_in)) * ((max_out) - (min_out)) / ((max_in) - (min_in)) + (min_out)
end
function utils.lerp(v, l, h)
return v * (h - l) + l
--- Linear interpolation.
-- Performs linear interpolation between 0 and 1 when `low` < `progress` < `high`.
-- @param progress (0-1)
-- @param low value to return when `progress` is 0
-- @param high value to return when `progress` is 1
-- @return number
function utils.lerp(progress, low, high)
return progress * (high - low) + low
end
function utils.smoothstep(v, l, h)
local t = utils.clamp((v - l) / (h - l), 0.0, 1.0)
--- Hermite interpolation.
-- Performs smooth Hermite interpolation between 0 and 1 when `low` < `progress` < `high`.
-- @param progress (0-1)
-- @param low value to return when `progress` is 0
-- @param high value to return when `progress` is 1
-- @return number
function utils.smoothstep(progress, low, high)
local t = utils.clamp((progress - low) / (high - low), 0.0, 1.0)
return t * t * (3.0 - 2.0 * t)
end
function utils.round(v, precision)
if precision then return utils.round(v / precision) * precision end
return v >= 0 and math.floor(v+0.5) or math.ceil(v-0.5)
--- Round number at a given precision.
-- Truncates `value` at `precision` points after the decimal (whole number if
-- left unspecified).
-- @param value
-- @param precision
-- @return number
function utils.round(value, precision)
if precision then return utils.round(value / precision) * precision end
return value >= 0 and math.floor(value+0.5) or math.ceil(value-0.5)
end
function utils.wrap(v, n)
if v < 0 then
v = v + utils.round(((-v/n)+1))*n
--- Wrap `value` around if it exceeds `limit`.
-- @param value
-- @param limit
-- @return number
function utils.wrap(value, limit)
if value < 0 then
value = value + utils.round(((-value/limit)+1))*limit
end
return v % n
return value % limit
end
-- from undef: https://love2d.org/forums/viewtopic.php?p=182219#p182219
-- check if a number is a power-of-two
function utils.is_pot(n)
return 0.5 == (frexp(n))
--- Check if a value is a power-of-two.
-- Returns true if a number is a valid power-of-two, otherwise false.
-- @author undef
-- @param value
-- @return boolean
function utils.is_pot(value)
-- found here: https://love2d.org/forums/viewtopic.php?p=182219#p182219
-- check if a number is a power-of-two
return (frexp(value)) == 0.5
end
return utils

View File

@ -24,6 +24,10 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
]]--
--- 2 dimensional vectors
-- @module vec2
-- @alias vector
local assert = assert
local sqrt, cos, sin, atan2 = math.sqrt, math.cos, math.sin, math.atan2

View File

@ -1,3 +1,4 @@
local assert = assert -- function() end
local sqrt, cos, sin, atan2, acos = math.sqrt, math.cos, math.sin, math.atan2, math.acos
local ffi = require "ffi"

View File

@ -27,12 +27,21 @@ THE SOFTWARE.
-- Modified to include 3D capabilities by Bill Shillito, April 2014
-- Various bug fixes by Colby Klein, October 2014
--- 3 dimensional vectors
-- @module vec3
-- @alias vector
local assert = assert
local sqrt, cos, sin, atan2, acos = math.sqrt, math.cos, math.sin, math.atan2, math.acos
local vector = {}
vector.__index = vector
--- Instance a new vec3.
-- @param x X value, table containing 3 elements, or another vector.
-- @param y Y value
-- @param z Z value
-- @return vec3
local function new(x,y,z)
-- allow construction via vec3(a, b, c), vec3 { a, b, c } or vec3 { x = a, y = b, z = c }
if type(x) == "table" then
@ -50,6 +59,8 @@ local unit_x = new(1,0,0)
local unit_y = new(0,1,0)
local unit_z = new(0,0,1)
--- Create a copy of the vec3 which does not reference the original data
-- @return vec3
function vector:clone()
return new(self.x, self.y, self.z)
end