2595 lines
97 KiB
Plaintext
2595 lines
97 KiB
Plaintext
-- *********************************
|
|
fn Thresh a b t =
|
|
if (distance a b) < t then
|
|
return true
|
|
else
|
|
return false
|
|
|
|
-- *********************************
|
|
fn rndP3 p3 n =
|
|
(
|
|
local mult = 10.0 ^ n
|
|
nx = (floor ((p3.x * mult) + 0.5)) / mult
|
|
ny = (floor ((p3.y * mult) + 0.5)) / mult
|
|
nz = (floor ((p3.z * mult) + 0.5)) / mult
|
|
return [nx,ny,nz]
|
|
)
|
|
|
|
-- *********************************
|
|
fn copyArray a =
|
|
(
|
|
b = #()
|
|
for i = 1 to a.count do
|
|
b[i] = a[i]
|
|
return b
|
|
)
|
|
|
|
-- *********************************
|
|
fn InitializeSelection =
|
|
(
|
|
freeSceneBitmaps()
|
|
SingleObject = false
|
|
AttachedTrunk = false
|
|
MagicIndex = undefined
|
|
ObjArray = selection as array
|
|
if ObjArray.count == 1 or ObjArray.count == 2 then
|
|
(
|
|
if ObjArray.count == 1 then
|
|
(
|
|
CTrunk = ObjArray[1]
|
|
CBranchec = undefined
|
|
) else (
|
|
if ObjArray[1].pivot.z < ObjArray[2].pivot.z then
|
|
(
|
|
CTrunk = ObjArray[1]
|
|
CBranches = ObjArray[2]
|
|
) else (
|
|
CTrunk = ObjArray[2]
|
|
CBranches = ObjArray[1]
|
|
)
|
|
)
|
|
for i = 1 to CTrunk.name.count do
|
|
if CTrunk.name[i] == "~" do MagicIndex = i
|
|
-- find the area from the name of the trunk object
|
|
Area = ""
|
|
if MagicIndex != undefined then
|
|
Area = substring CTrunk.name (Magicindex + 1) 2
|
|
else
|
|
MessageBox "Please make sure you have\nthe area information defined!\n\ni.e. \"VMyPlant~IJ10-00\""
|
|
return #(CTrunk, CBranches, Area)
|
|
) else (
|
|
MessageBox "Feed this tool 1 or 2 objects only"
|
|
return undefined
|
|
)
|
|
)
|
|
|
|
-- *********************************
|
|
fn projectPoints p3 p r =
|
|
(
|
|
-- usage: projectPoints <point in 3space the plane should intersect> <array of point3 values> <ray>
|
|
-- project the key vertices onto a plane perpendicular to the light
|
|
pp = #()
|
|
V = p3
|
|
N = r.dir
|
|
d = -(dot V N)
|
|
for i = 1 to p.count do
|
|
(
|
|
V = p[i]
|
|
rPos = V + r.dir * 10.0
|
|
NRay = ray rPos r.dir
|
|
t = -((d + (dot N rPos)) / (dot N r.dir))
|
|
P0 = rPos.x + r.dir.x * t
|
|
P1 = rPos.y + r.dir.y * t
|
|
P2 = rPos.z + r.dir.z * t
|
|
Pnt = [P0, P1, P2]
|
|
append pp Pnt
|
|
)
|
|
return pp
|
|
)
|
|
|
|
-- *********************************
|
|
fn projectObject o r =
|
|
(
|
|
-- projects all the vertices in an object onto a plane normal to the direction of a supplied ray.
|
|
-- usage: projectObject <object> <ray>
|
|
v = for i = 1 to o.numverts collect (getVert o i)
|
|
v2 = projectPoints o.center v r
|
|
for i = 1 to o.numverts do (setVert o i v2[i])
|
|
update o
|
|
)
|
|
|
|
-- *********************************
|
|
fn FlattenObject o r =
|
|
(
|
|
sel = (getBackFaces o r)
|
|
for i = sel.count to 1 by -1 do
|
|
deleteFace o sel[i]
|
|
projectObject o r
|
|
)
|
|
|
|
-- *********************************
|
|
fn getBackFaces o r =
|
|
(
|
|
s = #()
|
|
for i = 1 to o.numfaces do
|
|
if (dot (getFaceNormal o i) r.dir) < 0 do
|
|
append s i
|
|
return s
|
|
)
|
|
|
|
-- *********************************
|
|
fn CopyAndFlipFaces o =
|
|
(
|
|
sel = getFaceSelection o
|
|
sc = sel.count
|
|
fc = o.numfaces
|
|
setNumFaces o (o.numfaces + sc) true
|
|
for i = 1 to sc do
|
|
(
|
|
iFaceIndex = sel[i]
|
|
iFace = getFace o iFaceIndex
|
|
setFace o (fc + i) [iFace.x, iFace.z, iFace.y]
|
|
setFaceMatID o (fc + i) (getFaceMatID o sel[i])
|
|
setFaceSmoothGroup o (fc + i) (getFaceSmoothGroup o sel[i])
|
|
)
|
|
update o
|
|
for i = 1 to sc do
|
|
(
|
|
iTVFace = getTVFace o sel[i]
|
|
setTVFace o (fc + i) [iTVFace.x, iTVFace.z, iTVFace.y]
|
|
)
|
|
addModifier o (Smooth())
|
|
convertToMesh o
|
|
)
|
|
|
|
-- *********************************
|
|
fn QuickSort l r a =
|
|
(
|
|
if r > l do
|
|
(
|
|
i = l - 1
|
|
j = r
|
|
do (
|
|
do (i += 1) while a[i] < a[r]
|
|
while j > 1 do
|
|
(
|
|
j -= 1
|
|
if a[j] <= a[r] do Exit
|
|
)
|
|
t = a[i]
|
|
a[i] = a[j]
|
|
a[j] = t
|
|
) while (
|
|
i < j
|
|
)
|
|
a[j] = a[i]
|
|
a[i] = a[r]
|
|
a[r] = t
|
|
QuickSort l (i - 1) a
|
|
QuickSort (i + 1) r a
|
|
)
|
|
return a
|
|
)
|
|
|
|
-- *********************************
|
|
fn QuickSort2 l r a b =
|
|
(
|
|
if r > l do
|
|
(
|
|
i = l - 1
|
|
j = r
|
|
do (
|
|
do (i += 1) while a[i] < a[r]
|
|
while j > 1 do
|
|
(
|
|
j -= 1
|
|
if a[j] <= a[r] do Exit
|
|
)
|
|
t = a[i]
|
|
a[i] = a[j]
|
|
a[j] = t
|
|
|
|
t2 = b[i]
|
|
b[i] = b[j]
|
|
b[j] = t2
|
|
|
|
) while (
|
|
i < j
|
|
)
|
|
a[j] = a[i]
|
|
a[i] = a[r]
|
|
a[r] = t
|
|
|
|
b[j] = b[i]
|
|
b[i] = b[r]
|
|
b[r] = t2
|
|
|
|
QuickSort2 l (i - 1) a b
|
|
QuickSort2 (i + 1) r a b
|
|
)
|
|
return #(a,b)
|
|
)
|
|
|
|
-- *********************************
|
|
fn GetAngle p1 p2 =
|
|
(
|
|
-- tan(theta) = (p2.x - p1.x)
|
|
dx = (p2.x - p1.x) as float
|
|
dy = (p2.y - p1.y) as float
|
|
theta = atan (dx / dy)
|
|
return theta
|
|
)
|
|
|
|
-- *********************************
|
|
fn ccw p0 p1 p2 =
|
|
(
|
|
dx1 = p1.x - p0.x
|
|
dy1 = p1.y - p0.y
|
|
dx2 = p2.x - p0.x
|
|
dy2 = p2.y - p0.y
|
|
|
|
if (dx1 * dy2) > (dy1 * dx2) do return 1 -- left turn
|
|
if (dx1 * dy2) < (dy1 * dx2) do return -1 -- right turn
|
|
if (dx1 * dy2) == (dy1 * dx2) do
|
|
if (dx1 * dx2) < 0 or (dy1 * dy2) < 0 then
|
|
return -1
|
|
else
|
|
if ((dx1 * dx1) + (dy1 * dy1)) >= ((dx2 * dx2) + (dy2 * dy2)) then
|
|
return 0
|
|
else
|
|
return 1
|
|
)
|
|
|
|
-- *********************************
|
|
fn IdentifyEdges b i =
|
|
(
|
|
local p = #()
|
|
iHeight = b.height
|
|
iWidth = b.width
|
|
|
|
-- make sure the top point is in the array
|
|
for y = 0 to (iHeight - 1) by 1 do
|
|
(
|
|
CRow = getPixels b [0,y] iWidth
|
|
for x = 1 to iWidth do
|
|
if CRow[x].value >= 253 do (append p [x - 1,y]; Exit)
|
|
if p.count >= 1 do Exit
|
|
)
|
|
|
|
-- make sure the bottom point is in the array
|
|
for y = (iHeight - 1) to 0 by -1 do
|
|
(
|
|
CRow = getPixels b [0,y] iWidth
|
|
for x = 1 to iWidth do
|
|
if CRow[x].value >= 253 do (append p [x - 1,y]; Exit)
|
|
if p.count >= 2 do Exit
|
|
)
|
|
|
|
for y = 0 to (iHeight - 1) by i do
|
|
(
|
|
CRow = getPixels b [0,y] iWidth
|
|
for x = 1 to iWidth do
|
|
if CRow[x].value >= 253 do (append p [x - 1,y]; Exit)
|
|
for x = iWidth to 1 by -1 do
|
|
if CRow[x].value >= 253 do (append p [x - 1,y]; Exit)
|
|
)
|
|
return p
|
|
)
|
|
|
|
fn ArrayCompare foo a b =
|
|
(
|
|
same = true
|
|
for i = 1 to a.count do
|
|
if a[i] != b[i] do same = false
|
|
return same
|
|
)
|
|
|
|
-- *********************************
|
|
fn GetElement p M =
|
|
(
|
|
if M <= 0 do
|
|
M += p.count
|
|
|
|
if M > p.count do
|
|
M -= p.count
|
|
return P[M]
|
|
)
|
|
|
|
-- *********************************
|
|
fn rnd num = (num + 0.5) as integer
|
|
|
|
-- *********************************
|
|
fn AvgPoint2 p1 p2 = [rnd ((p1.x + p2.x) as float / 2), rnd ((p1.y + p2.y) as float / 2)]
|
|
|
|
-- *********************************
|
|
fn pruneClosePoints p threshold =
|
|
(
|
|
n = #()
|
|
local clean = true
|
|
local skip = false
|
|
for i = 1 to p.count do
|
|
(
|
|
if skip then
|
|
skip = false
|
|
else
|
|
(
|
|
-- get the distance between the two points
|
|
d = distance (p1 = (getElement p i)) (p2 = (getElement p (i+1)))
|
|
--format "d: %\n" d
|
|
if d <= threshold then
|
|
(
|
|
append n (AvgPoint2 p1 p2)
|
|
skip = true
|
|
clean = false
|
|
)
|
|
else append n p1
|
|
)
|
|
)
|
|
if (ArrayCompare true p n) do return p
|
|
if clean == false then
|
|
(
|
|
--format "going again...\n"
|
|
pruneClosePoints n threshold
|
|
) else (
|
|
return n
|
|
)
|
|
)
|
|
|
|
-- *********************************
|
|
fn GrahamScanBitmap CBitmap Yi PruneDistance=
|
|
(
|
|
CBitmap = (BitmapThreshold CBitmap 180)
|
|
p = IdentifyEdges CBitMap Yi
|
|
Hullpoints = GrahamScan p
|
|
HullPoints = pruneClosePoints HullPoints PruneDistance
|
|
return HullPoints
|
|
)
|
|
|
|
-- *********************************
|
|
fn GrahamScan p =
|
|
(
|
|
N = p.count
|
|
lowPt = p[N]
|
|
AnchorIndex = N
|
|
local HullPoints = #(), AngleArray = #()
|
|
for i = 1 to N do
|
|
if (p[i].y < lowPt.y) then
|
|
(
|
|
lowPt = p[i]
|
|
AnchorIndex = i
|
|
)
|
|
else
|
|
if (p[i].y == lowPt.y) then
|
|
if (p[i].x < lowPt.x) do
|
|
(
|
|
lowPt = p[i]
|
|
AnchorIndex = i
|
|
)
|
|
-- Calculate the angles from the anchorpoint to each other point
|
|
AnchorPt = p[AnchorIndex]
|
|
append HullPoints AnchorPt
|
|
for i = 1 to N do
|
|
if i != AnchorIndex then
|
|
append AngleArray (getAngle AnchorPt p[i])
|
|
else
|
|
append AngleArray -360.0
|
|
-- sort the angles
|
|
quickSort2 1 AngleArray.count AngleArray p
|
|
|
|
p[1] = p[N]
|
|
M = 3
|
|
for i = 4 to N do
|
|
(
|
|
while (ccw (GetElement p M) (GetElement p (M - 1)) p[i]) <= 0 do (M -= 1)
|
|
M += 1
|
|
t = p[M]
|
|
p[M] = p[i]
|
|
p[i] = t
|
|
)
|
|
for i = 2 to M do append Hullpoints p[i]
|
|
gc()
|
|
return HullPoints
|
|
)
|
|
|
|
-- *********************************
|
|
fn scaleColor c s = (color (c.r * s) (c.g * s) (c.b * s))
|
|
|
|
fn scaleColor2 c s =
|
|
(
|
|
r = (c.r * s)
|
|
g = (c.g * s)
|
|
b = (c.b * s)
|
|
if r > 255 do r = 255
|
|
if r < 0 do r = 0
|
|
if g > 255 do g = 255
|
|
if g < 0 do g = 0
|
|
if b > 255 do b = 255
|
|
if b < 0 do b = 0
|
|
return (color r g b)
|
|
)
|
|
|
|
-- *********************************
|
|
fn CreateBitmap w h c =
|
|
(
|
|
b = bitmap w h
|
|
local cArray = for i = 1 to w collect c
|
|
for y = 0 to (h - 1) do (SetPixels b [0, y] cArray)
|
|
return b
|
|
)
|
|
|
|
-- *********************************
|
|
fn PowOfLimit x y =
|
|
(
|
|
if x > y then
|
|
(
|
|
SclDn = 0
|
|
while x > 256 do
|
|
(
|
|
x *= 0.5
|
|
SclDn += 1
|
|
)
|
|
if SClDn > 0 do
|
|
for i = 1 to SClDn do y *= 0.5
|
|
) else (
|
|
SclDn = 0
|
|
while y > 256 do
|
|
(
|
|
y *= 0.5
|
|
SclDn += 1
|
|
)
|
|
if SClDn > 0 do
|
|
for i = 1 to SClDn do x *= 0.5
|
|
)
|
|
if x < 8 do x = 8
|
|
if y < 8 do y = 8
|
|
return [x,y]
|
|
)
|
|
|
|
-- *********************************
|
|
-- returns a power of two number based on user input of higher, lower, or nearest
|
|
fn NearPowOfTwo num weight =
|
|
(
|
|
-- Highest
|
|
if weight == 1 do
|
|
(
|
|
num2 = num
|
|
counter = 0
|
|
while num >= 1.0 do
|
|
(
|
|
num = (num * 0.5)
|
|
counter = counter + 1
|
|
)
|
|
p2 = 2^(counter)
|
|
return p2
|
|
)
|
|
|
|
-- Lowest
|
|
if weight == 2 do
|
|
(
|
|
num2 = num
|
|
counter = 0
|
|
while num >= 1.0 do
|
|
(
|
|
num = (num * 0.5)
|
|
counter = counter + 1
|
|
)
|
|
p2 = 2^(counter - 1)
|
|
return p2
|
|
)
|
|
|
|
-- Nearest
|
|
if weight == 3 do
|
|
(
|
|
num2 = num
|
|
counter = 0
|
|
while num >= 1.0 do
|
|
(
|
|
num = (num * 0.5)
|
|
counter = counter + 1
|
|
)
|
|
p2 = 2^(counter - 1)
|
|
if (num2 > p2 * 1.5) then
|
|
return (p2 * 2)
|
|
else
|
|
return p2
|
|
)
|
|
)
|
|
|
|
-- *********************************
|
|
-- returns the index of the vertex with the lowest pos.z value
|
|
fn LowestVert obj =
|
|
(
|
|
local LowVertPos = obj.max.z
|
|
local LowestVert = -1
|
|
nv = obj.numverts
|
|
for i = 1 to nv do
|
|
(
|
|
local Cvert = getvert obj i
|
|
if Cvert.z < LowVertPos do
|
|
(
|
|
LowVertPos = Cvert.z
|
|
LowestVert = i
|
|
)
|
|
)
|
|
return LowestVert
|
|
)
|
|
|
|
-- *********************************
|
|
fn trunkCenter CObj thresh =
|
|
(
|
|
-- first, we find the lowest vertex in the model
|
|
LowVert = lowestVert CObj
|
|
-- searching from the bottom
|
|
BottomPoint = CObj.min.z
|
|
SetVertSelection CObj #()
|
|
update CObj
|
|
nv = CObj.numverts
|
|
Verts = for i = 1 to nv collect (getvert CObj i)
|
|
-- first we find the vertex distance furthest from the center of the object
|
|
FarVert = 0.0
|
|
VertexDistances = #()
|
|
-- we put all the vertex distances into an array, and find the one furthest from the center of the mesh
|
|
for i = 1 to nv do
|
|
(
|
|
append VertexDistances Verts[i].z
|
|
if VertexDistances[i] < FarVert do FarVert = VertexDistances[i]
|
|
)
|
|
-- now we flag any vert within the threshold and put it into an array
|
|
VertSelection = #()
|
|
for i = 1 to nv do
|
|
if VertexDistances[i] <= (BottomPoint + thresh) do (append VertSelection i)
|
|
SetVertSelection CObj VertSelection
|
|
verts = [0,0,0]
|
|
for i = 1 to VertSelection.count do
|
|
Verts = Verts + (getVert CObj VertSelection[i])
|
|
|
|
VertCenter = [(Verts.x / VertSelection.count), (Verts.y / VertSelection.count), (Verts.z / VertSelection.count)]
|
|
return VertCenter
|
|
)
|
|
|
|
-- *********************************
|
|
-- crops a bitmap to new supplied dimensions
|
|
fn CropBitmap SourceImage StartPos NewImageSize =
|
|
(
|
|
width = SourceImage.width
|
|
height = SourceImage.height
|
|
bmap = BitMap NewImageSize.x NewImageSize.y
|
|
NewY = 0
|
|
for y = StartPos.y to (StartPos.y + NewImageSize.y) do
|
|
(
|
|
CRow = getPixels SourceImage [StartPos.x, y] NewImageSize.x
|
|
setPixels bmap [0,NewY] CRow
|
|
NewY += 1
|
|
)
|
|
return bmap
|
|
)
|
|
|
|
-- *********************************
|
|
-- takes a bitmap and returns an array of the following:
|
|
-- [1] a new bitmap that only contains black or white (on/off transparencey)
|
|
-- [2] the start point [x,y] for cropping
|
|
-- [3] the area of a closest fit rectangle about the opaque area of the opacity map from the start point at [2]
|
|
fn ThresholdBitmap bmap Thresh =
|
|
(
|
|
local NMap = copy BMap
|
|
StartPoint = [0,0]
|
|
NewSize = [NMap.width, NMap.height]
|
|
width = NMap.width
|
|
height = NMap.height
|
|
AreaArray = #()
|
|
for y = 1 to height do
|
|
(
|
|
AreaArray[y] = #()
|
|
CRow = getpixels NMap [0, (y - 1)] width
|
|
-- convert the row of color pixels to values
|
|
LumRow = for i = 1 to CRow.count collect (CRow[i].value)
|
|
-- convert this row based on the threshold value
|
|
for i = 1 to LumRow.count do
|
|
if LumRow[i] > Thresh then
|
|
(
|
|
AreaArray[y][i] = true
|
|
LumRow[i] = 255
|
|
) else (
|
|
AreaArray[y][i] = false
|
|
LumRow[i] = 0
|
|
)
|
|
-- convert the values back into colors
|
|
for i = 1 to LumRow.count do
|
|
CRow[i] = (color LumRow[i] LumRow[i] LumRow[i])
|
|
-- write the row back into the bitmap
|
|
setpixels NMap [0, (y - 1)] CRow
|
|
)
|
|
|
|
maxX = 0
|
|
minX = 256
|
|
maxY = 0
|
|
minY = 256
|
|
|
|
for y = 1 to AreaArray.count do
|
|
(
|
|
CRow = AreaArray[y]
|
|
for x = 1 to CRow.count do
|
|
if CRow[x] == true do
|
|
(
|
|
if x > maxX do maxX = x
|
|
if y > maxY do maxY = y
|
|
if x < minX do minX = x
|
|
if y < minY do minY = y
|
|
)
|
|
)
|
|
NewStartPoint = [(minX - 1), (minY - 1)]
|
|
NewMapSize = [(maxX - minX) + 1, (maxY - minY) + 1]
|
|
if NewStartPoint == [255,255] or NewMapSize == [-255,-255] do
|
|
(
|
|
format "Bad OpacityMap data\n"
|
|
NewStartPoint = [0,0]
|
|
NewMapSize = NewSize
|
|
)
|
|
return #(NMap, NewStartPoint, NewMapSize)
|
|
)
|
|
|
|
-- ************************************************************************************************
|
|
-- * Start Utility
|
|
-- ************************************************************************************************
|
|
Utility DetailReduction "Detail Reduction"
|
|
(
|
|
local DRRollout, WorkingFolder, AttachedTrunk, SingleObject, Flt
|
|
|
|
local debug = false
|
|
|
|
rollout DRRollout "Detail Reduction"
|
|
(
|
|
local CObj, CTrunk, CBranches, ThinkCount = 0,
|
|
InterfaceState = #(),
|
|
MasterObjData = #(),
|
|
SunArray = #([0.163287,-0.71436,0.680461], [0.150228,-0.623607,0.767167], [0.13906,-0.522188,0.841417], [0.129977,-0.411837,0.90194], [0.123134,-0.294445,0.947703], [0.118652,-0.17202,0.977922], [0.116608,-0.0466583,0.992081], [0.11704,0.0794943,0.989941], [0.11994,0.204279,0.971537], [0.125262,0.32556,0.937187], [0.132916,0.441262,0.88748])
|
|
|
|
local DefaultInterface = #(false,\ --renderSeperate
|
|
false,\ --CenterToBase,
|
|
0.5,\ -- TrunkCenterThresh
|
|
127,\ -- OpacityThresh
|
|
true,\ -- RescaleBitmaps
|
|
1,\ -- sizeMaps
|
|
32,\ -- PixelsPerMeter
|
|
4,\ -- YIncrement
|
|
10.0,\ -- PrunePointsThreshold
|
|
0.24,\ -- AngleJitter
|
|
true,\ -- GenTrunk
|
|
false,\ -- CameraAtEyeHeight
|
|
false,\ -- isPrelit
|
|
256,\ -- BitMapSize
|
|
5,\ -- NumViews
|
|
1,\ -- DRLevel
|
|
false,\ -- OverRideBitmapSize
|
|
256,\ -- TrunkWidthOveride
|
|
256,\ -- TrunkHeightOveride
|
|
true,\ -- GenBranches
|
|
true,\ -- BranchCameraAtEyeHeight
|
|
true,\ -- SplitMethod
|
|
256,\ -- BranchBitMapSize
|
|
5,\ -- BranchNumViews
|
|
1,\ -- BranchDRLevel
|
|
false,\ -- BranchOverRideBitmapSize
|
|
256,\ -- BranchWidthOveride
|
|
256,\ -- BranchHeightOveride
|
|
true) -- AutoDetermineMapSizes
|
|
|
|
group "Batch Options"
|
|
(
|
|
ListBox BatchList "Batch Processing List:" height:5 width:250
|
|
editText BatchName "Batch Name:" text:"Detail Reduction Set 1" width:250
|
|
checkbutton EditName "Edit" offset:[130,-23] height:19 highlightcolor:(color 69 163 172) width:80
|
|
button Add "Add Selection" width:80 height:32 offset:[130,-99]
|
|
button Remove "Remove" width:80 height:32 offset:[130,0]
|
|
label blank0 offset:[0,5]
|
|
checkbox UseObjName "Use Obj Name" checked:true
|
|
checkbox AutoSelect "Auto Select" offset:[130,-20]
|
|
checkbox ThinkForMe "Think for Me" align:#right offset:[0,-20]
|
|
)
|
|
|
|
group "Global Parameters"
|
|
(
|
|
dropDownList GameArea "Game Area Lighting:" items:#("Beach", "Jungle Road", "Platation House", "Industrial Jungle", "InGEN Town", "Plains", "PineValley", "Shore", "InGEN Lab", "Ascent", "Summit") selection:2 height:12
|
|
colorpicker AmbientCol "Ambient Light: " color:(color 90 90 90) offset:[-50,0]
|
|
spinner CMult "Spotlight Multiplier: " range:[0.1, 5.0, 0.5] fieldwidth:35 offset:[-20,-23]
|
|
)
|
|
|
|
group "General Options"
|
|
(
|
|
checkBox renderSeperate "Detail reduce branches seperate from trunk"
|
|
checkbox CenterToBase "Center camera based on trunk bottom" checked:false
|
|
spinner TrunkCenterThresh "Threshold:" range:[0,10,0.5] fieldWidth:45 align:#right enabled:false offset:[0,-20]
|
|
spinner OpacityThresh "Opacity Map Threshold: " range:[0,255,127] type:#integer fieldwidth:45 offset:[0,0]
|
|
Checkbox RescaleBitmaps "Rescale bitmaps" offset:[0,-20] checked:true
|
|
radiobuttons sizeMaps labels:#("Higher power of 2", "Lower power of 2", "Nearest power of 2") default:1 columns:3 align:#left
|
|
spinner PixelsPerMeter "Pixels Per Meter: " range:[1,64,32] fieldWidth:45
|
|
checkbox AutoDetermineMapSizes "Auto Determine Map Sizes" offset:[0,-20] checked:true
|
|
)
|
|
|
|
group "Convex Hull Parameters"
|
|
(
|
|
spinner YIncrement "Y Increment" range:[1,32,4] type:#integer fieldWidth:35 align:#left
|
|
spinner PrunePointsThreshold "Pixel Threshold:" range:[1,32,10] fieldWidth:35 offset:[0,-20] align:#center
|
|
spinner AngleJitter "Pixel Jitter:" range:[0,1,0.24] fieldWidth:35 align:#right offset:[0,-20]
|
|
)
|
|
|
|
group "Trunk Options"
|
|
(
|
|
checkbox GenTrunk "Create" checked:true
|
|
checkbox CameraAtEyeHeight "Camera at eye level" align:#center offset:[0,-20]
|
|
checkbox isPrelit "Trunk is Prelit" align:#right offset:[0,-20]
|
|
spinner BitMapSize "Map Size:" range:[8,512,256] type:#integer align:#left fieldwidth:35
|
|
spinner NumViews "# Views: " range:[2,9,5] type:#integer fieldwidth:35 offset:[0,-21] align:#center
|
|
spinner DRLevel "Detail Level: " range:[1,4,1] type:#integer fieldwidth:25 offset:[0,-21] align:#right
|
|
checkbox OverRideBitmapSize "Overide Bitmap Size"
|
|
spinner TrunkWidthOveride "Width:" range:[8,256,256] type:#integer fieldwidth:45 align:#left enabled:false offset:[130,-20]
|
|
spinner TrunkHeightOveride "Height:" range:[8,256,256] type:#integer fieldwidth:45 offset:[230,-21] enabled:false align:#left
|
|
)
|
|
|
|
group "Branch Options"
|
|
(
|
|
checkbox GenBranches "Create" enabled:false checked:true
|
|
checkbox BranchCameraAtEyeHeight "Camera at eye level" align:#center offset:[0,-20] enabled:false checked:true
|
|
checkbox SplitMethod "Use Split Method" checked:true align:#right offset:[0,-20] enabled:false
|
|
spinner BranchBitMapSize "Map Size:" range:[8,512,256] type:#integer align:#left fieldwidth:35 enabled:false
|
|
spinner BranchNumViews "# Views: " range:[2,9,5] type:#integer fieldwidth:35 align:#center offset:[0,-21] enabled:false
|
|
spinner BranchDRLevel "Detail Level: " range:[1,4,1] type:#integer fieldwidth:25 offset:[0,-21] align:#right enabled:false
|
|
checkbox BranchOverRideBitmapSize "Overide Bitmap Size" enabled:false
|
|
spinner BranchWidthOveride "Width:" range:[8,256,256] type:#integer fieldwidth:45 align:#left enabled:false offset:[130,-20]
|
|
spinner BranchHeightOveride "Height:" range:[8,256,256] type:#integer fieldwidth:45 offset:[230,-21] enabled:false align:#left
|
|
)
|
|
|
|
Button CreateDRObject "Create Detail Reduced Version" height:40 align:#left offset:[-10,10] width:180
|
|
Button CreateShadowObject "Create Shadow Version" width:180 height:40 align:#right offset:[10,-46]
|
|
label status1
|
|
|
|
on BatchName entered text do
|
|
(
|
|
if EditName.checked do
|
|
(
|
|
txt = BatchName.text
|
|
names = BatchList.items
|
|
s = BatchList.selection
|
|
names[s] = txt
|
|
BatchList.items = names
|
|
)
|
|
)
|
|
|
|
on EditName changed state do
|
|
(
|
|
if state then
|
|
(
|
|
names = BatchList.items
|
|
if names.count > 0 do
|
|
(
|
|
s = BatchList.selection
|
|
BatchName.text = names[s]
|
|
)
|
|
) else (
|
|
names = BatchList.items
|
|
BatchName.text = ("Detail Reduction Set " + (names.count + 1) as string)
|
|
)
|
|
|
|
)
|
|
on ThinkForMe changed state do
|
|
(
|
|
ThinkCount += 1
|
|
if ThinkCount >= 0 and ThinkCount <= 3 do messageBox "If computers were so wise...."
|
|
if ThinkCount > 3 and ThinkCount < 7 do messageBox "pesky little fucker...."
|
|
if ThinkCount >= 7 and ThinkCount < 10 do messageBox "just give up!"
|
|
if ThinkCount >= 10 do messageBox "keep it up.....\nhere comes something really cool"
|
|
ThinkForMe.checked = false
|
|
)
|
|
on BatchList selected s do
|
|
(
|
|
renderSeperate.checked = InterfaceState[s][1]
|
|
CenterToBase.checked = InterfaceState[s][2]
|
|
TrunkCenterThresh.value = InterfaceState[s][3]
|
|
OpacityThresh.value = InterfaceState[s][4]
|
|
RescaleBitmaps.checked = InterfaceState[s][5]
|
|
sizeMaps.state = InterfaceState[s][6]
|
|
PixelsPerMeter.value = InterfaceState[s][7]
|
|
YIncrement.value = InterfaceState[s][8]
|
|
PrunePointsThreshold.value = InterfaceState[s][9]
|
|
AngleJitter.value = InterfaceState[s][10]
|
|
GenTrunk.checked = InterfaceState[s][11]
|
|
CameraAtEyeHeight.checked = InterfaceState[s][12]
|
|
isPrelit.checked = InterfaceState[s][13]
|
|
BitMapSize.value = InterfaceState[s][14]
|
|
NumViews.value = InterfaceState[s][15]
|
|
DRLevel.value = InterfaceState[s][16]
|
|
OverRideBitmapSize.checked = InterfaceState[s][17]
|
|
TrunkWidthOveride.value = InterfaceState[s][18]
|
|
TrunkHeightOveride.value = InterfaceState[s][19]
|
|
GenBranches.checked = InterfaceState[s][20]
|
|
BranchCameraAtEyeHeight.checked = InterfaceState[s][21]
|
|
SplitMethod.checked = InterfaceState[s][22]
|
|
BranchBitMapSize.value = InterfaceState[s][23]
|
|
BranchNumViews.value = InterfaceState[s][24]
|
|
BranchDRLevel.value = InterfaceState[s][25]
|
|
BranchOverRideBitmapSize.checked = InterfaceState[s][26]
|
|
BranchWidthOveride.value = InterfaceState[s][27]
|
|
BranchHeightOveride.value = InterfaceState[s][28]
|
|
AutoDetermineMapSizes.checked = InterfaceState[s][29]
|
|
|
|
if CenterToBase.checked then
|
|
TrunkCenterThresh.enabled = true
|
|
else
|
|
TrunkCenterThresh.enabled = false
|
|
|
|
if renderSeperate.checked then
|
|
SplitMethod.enabled = BranchBitMapSize.enabled = BranchNumViews.enabled = BranchDRLevel.enabled = GenBranches.enabled = BranchCameraAtEyeHeight.enabled = BranchOverRideBitmapSize.enabled = true
|
|
else
|
|
SplitMethod.enabled = BranchBitMapSize.enabled = BranchNumViews.enabled = BranchDRLevel.enabled = GenBranches.enabled = BranchCameraAtEyeHeight.enabled = BranchOverRideBitmapSize.enabled = BranchWidthOveride.enabled = BranchHeightOveride.enabled = false
|
|
|
|
if OverRideBitmapSize.checked then
|
|
TrunkWidthOveride.enabled = TrunkHeightOveride .enabled = true
|
|
else
|
|
TrunkWidthOveride.enabled = TrunkHeightOveride .enabled = false
|
|
|
|
if BranchOverRideBitmapSize.checked then
|
|
BranchWidthOveride.enabled = BranchHeightOveride .enabled = true
|
|
else
|
|
BranchWidthOveride.enabled = BranchHeightOveride .enabled = false
|
|
|
|
if AutoSelect.checked do
|
|
(
|
|
select MasterObjData[s][1]
|
|
if MasterObjData[s][2] != undefined do selectmore MasterObjData[s][2]
|
|
)
|
|
|
|
if EditName.checked do
|
|
(
|
|
names = BatchList.items
|
|
if names.count > 0 do
|
|
(
|
|
s = BatchList.selection
|
|
BatchName.text = names[s]
|
|
)
|
|
)
|
|
)
|
|
|
|
on add pressed do
|
|
(
|
|
if (ObjData = InitializeSelection()) != undefined do
|
|
(
|
|
format "%\n" ObjData
|
|
append MasterObjData ObjData
|
|
append InterfaceState (copyArray DefaultInterface)
|
|
BatchListNames = BatchList.items
|
|
if UseObjName.checked then
|
|
(
|
|
nm = ObjData[1].name
|
|
nm = (substring nm 1 (nm.count - 3))
|
|
append BatchListNames nm
|
|
) else (
|
|
append BatchListNames BatchName.text
|
|
)
|
|
BatchList.items = BatchListNames
|
|
BatchName.text = ("Detail Reduction Set " + (BatchListNames.count + 1) as string)
|
|
)
|
|
)
|
|
|
|
on remove pressed do
|
|
(
|
|
s = BatchList.selection
|
|
if MasterObjData.count >= 1 do
|
|
(
|
|
deleteItem MasterObjData s
|
|
BatchListNames = BatchList.items
|
|
deleteItem BatchListNames s
|
|
BatchList.items = BatchListNames
|
|
if s >= 2 then
|
|
BatchList.selection = (s - 1)
|
|
else
|
|
BatchList.selection = 1
|
|
BatchName.text = ("Detail Reduction Set " + (BatchListNames.count + 1) as string)
|
|
)
|
|
)
|
|
|
|
-- **************************************************************
|
|
-- Interface Control Modifications
|
|
-- **************************************************************
|
|
|
|
-- 1
|
|
on renderSeperate changed state do
|
|
(
|
|
if renderSeperate.checked then
|
|
SplitMethod.enabled = BranchBitMapSize.enabled = BranchNumViews.enabled = BranchDRLevel.enabled = GenBranches.enabled = BranchCameraAtEyeHeight.enabled = BranchOverRideBitmapSize.enabled = true
|
|
else
|
|
SplitMethod.enabled = BranchBitMapSize.enabled = BranchNumViews.enabled = BranchDRLevel.enabled = GenBranches.enabled = BranchCameraAtEyeHeight.enabled = BranchOverRideBitmapSize.enabled = BranchWidthOveride.enabled = BranchHeightOveride.enabled = false
|
|
if InterfaceState.count >= 1 do
|
|
InterfaceState[BatchList.selection][1] = renderSeperate.checked
|
|
)
|
|
|
|
-- 2
|
|
on CenterToBase changed state do
|
|
(
|
|
if CenterToBase.checked then
|
|
TrunkCenterThresh.enabled = true
|
|
else
|
|
TrunkCenterThresh.enabled = false
|
|
if InterfaceState.count >= 1 do
|
|
InterfaceState[BatchList.selection][2] = CenterToBase.checked
|
|
)
|
|
|
|
-- 3
|
|
on TrunkCenterThresh changed state do
|
|
if InterfaceState.count >= 1 do
|
|
InterfaceState[BatchList.selection][3] = TrunkCenterThresh.value
|
|
-- 4
|
|
on OpacityThresh changed state do
|
|
if InterfaceState.count >= 1 do
|
|
InterfaceState[BatchList.selection][4] = OpacityThresh.value
|
|
-- 5
|
|
on RescaleBitmaps changed state do
|
|
if InterfaceState.count >= 1 do
|
|
InterfaceState[BatchList.selection][5] = RescaleBitmaps.checked
|
|
-- 6
|
|
on sizeMaps changed state do
|
|
if InterfaceState.count >= 1 do
|
|
InterfaceState[BatchList.selection][6] = sizeMaps.state
|
|
-- 7
|
|
on PixelsPerMeter changed state do
|
|
if InterfaceState.count >= 1 do
|
|
InterfaceState[BatchList.selection][7] = PixelsPerMeter.value
|
|
-- 8
|
|
on YIncrement changed state do
|
|
if InterfaceState.count >= 1 do
|
|
InterfaceState[BatchList.selection][8] = YIncrement.value
|
|
-- 9
|
|
on PrunePointsThreshold changed state do
|
|
if InterfaceState.count >= 1 do
|
|
InterfaceState[BatchList.selection][9] = PrunePointsThreshold.value
|
|
-- 10
|
|
on AngleJitter changed state do
|
|
if InterfaceState.count >= 1 do
|
|
InterfaceState[BatchList.selection][10] = AngleJitter.value
|
|
-- 11
|
|
on GenTrunk changed state do
|
|
if InterfaceState.count >= 1 do
|
|
InterfaceState[BatchList.selection][11] = GenTrunk.checked
|
|
-- 12
|
|
on CameraAtEyeHeight changed state do
|
|
if InterfaceState.count >= 1 do
|
|
InterfaceState[BatchList.selection][12] = CameraAtEyeHeight.checked
|
|
-- 13
|
|
on isPrelit changed state do
|
|
if InterfaceState.count >= 1 do
|
|
InterfaceState[BatchList.selection][13] = isPrelit.checked
|
|
-- 14
|
|
on BitMapSize changed state do
|
|
if InterfaceState.count >= 1 do
|
|
InterfaceState[BatchList.selection][14] = BitMapSize.value
|
|
-- 15
|
|
on NumViews changed state do
|
|
if InterfaceState.count >= 1 do
|
|
InterfaceState[BatchList.selection][15] = NumViews.value
|
|
-- 16
|
|
on DRLevel changed state do
|
|
(
|
|
BranchDRLevel.value = DRLevel.value
|
|
if InterfaceState.count >= 1 do
|
|
(
|
|
InterfaceState[BatchList.selection][16] = DRLevel.value
|
|
InterfaceState[BatchList.selection][25] = BranchDRLevel.value
|
|
)
|
|
)
|
|
-- 17
|
|
on OverRideBitmapSize changed state do
|
|
(
|
|
if OverRideBitmapSize.checked then
|
|
TrunkWidthOveride.enabled = TrunkHeightOveride .enabled = true
|
|
else
|
|
TrunkWidthOveride.enabled = TrunkHeightOveride .enabled = false
|
|
if InterfaceState.count >= 1 do
|
|
InterfaceState[BatchList.selection][17] = OverRideBitmapSize.checked
|
|
)
|
|
-- 18
|
|
on TrunkWidthOveride changed state do
|
|
if InterfaceState.count >= 1 do
|
|
InterfaceState[BatchList.selection][18] = TrunkWidthOveride.value
|
|
-- 19
|
|
on TrunkHeightOveride changed state do
|
|
if InterfaceState.count >= 1 do
|
|
InterfaceState[BatchList.selection][19] = TrunkHeightOveride.value
|
|
-- 20
|
|
on GenBranches changed state do
|
|
if InterfaceState.count >= 1 do
|
|
InterfaceState[BatchList.selection][20] = GenBranches.checked
|
|
-- 21
|
|
on BranchCameraAtEyeHeight changed state do
|
|
if InterfaceState.count >= 1 do
|
|
InterfaceState[BatchList.selection][21] = BranchCameraAtEyeHeight.checked
|
|
-- 22
|
|
on SplitMethod changed state do
|
|
if InterfaceState.count >= 1 do
|
|
InterfaceState[BatchList.selection][22] = SplitMethod.checked
|
|
-- 23
|
|
on BranchBitMapSize changed state do
|
|
if InterfaceState.count >= 1 do
|
|
InterfaceState[BatchList.selection][23] = BranchBitMapSize.value
|
|
-- 24
|
|
on BranchNumViews changed state do
|
|
if InterfaceState.count >= 1 do
|
|
InterfaceState[BatchList.selection][24] = BranchNumViews.value
|
|
-- 25
|
|
on BranchDRLevel changed state do
|
|
(
|
|
DRLevel.value = BranchDRLevel.value
|
|
if InterfaceState.count >= 1 do
|
|
(
|
|
InterfaceState[BatchList.selection][16] = DRLevel.value
|
|
InterfaceState[BatchList.selection][25] = BranchDRLevel.value
|
|
)
|
|
)
|
|
-- 26
|
|
on BranchOverRideBitmapSize changed state do
|
|
(
|
|
if BranchOverRideBitmapSize.checked then
|
|
BranchWidthOveride.enabled = BranchHeightOveride .enabled = true
|
|
else
|
|
BranchWidthOveride.enabled = BranchHeightOveride .enabled = false
|
|
if InterfaceState.count >= 1 do
|
|
InterfaceState[BatchList.selection][26] = BranchOverRideBitmapSize.checked
|
|
)
|
|
-- 27
|
|
on BranchWidthOveride changed state do
|
|
if InterfaceState.count >= 1 do
|
|
InterfaceState[BatchList.selection][27] = BranchWidthOveride.value
|
|
-- 28
|
|
on BranchHeightOveride changed state do
|
|
if InterfaceState.count >= 1 do
|
|
InterfaceState[BatchList.selection][28] = BranchHeightOveride.value
|
|
|
|
on AutoDetermineMapSizes changed state do
|
|
if InterfaceState.count >= 1 do
|
|
InterfaceState[BatchList.selection][29] = AutoDetermineMapSizes.checked
|
|
|
|
-- *******************************************************************************************************
|
|
-- * Generate Detail Reduced version of the object
|
|
-- *******************************************************************************************************
|
|
on CreateDRObject pressed do
|
|
(
|
|
freeSceneBitmaps()
|
|
for s = 1 to InterfaceState.count do
|
|
(
|
|
if debug do format "\n\nStarting Object %\n\n" s
|
|
BatchList.selection = s
|
|
renderSeperate.checked = InterfaceState[s][1]
|
|
CenterToBase.checked = InterfaceState[s][2]
|
|
TrunkCenterThresh.value = InterfaceState[s][3]
|
|
OpacityThresh.value = InterfaceState[s][4]
|
|
RescaleBitmaps.checked = InterfaceState[s][5]
|
|
sizeMaps.state = InterfaceState[s][6]
|
|
PixelsPerMeter.value = InterfaceState[s][7]
|
|
YIncrement.value = InterfaceState[s][8]
|
|
PrunePointsThreshold.value = InterfaceState[s][9]
|
|
AngleJitter.value = InterfaceState[s][10]
|
|
GenTrunk.checked = InterfaceState[s][11]
|
|
CameraAtEyeHeight.checked = InterfaceState[s][12]
|
|
isPrelit.checked = InterfaceState[s][13]
|
|
BitMapSize.value = InterfaceState[s][14]
|
|
NumViews.value = InterfaceState[s][15]
|
|
DRLevel.value = InterfaceState[s][16]
|
|
OverRideBitmapSize.checked = InterfaceState[s][17]
|
|
TrunkWidthOveride.value = InterfaceState[s][18]
|
|
TrunkHeightOveride.value = InterfaceState[s][19]
|
|
GenBranches.checked = InterfaceState[s][20]
|
|
BranchCameraAtEyeHeight.checked = InterfaceState[s][21]
|
|
SplitMethod.checked = InterfaceState[s][22]
|
|
BranchBitMapSize.value = InterfaceState[s][23]
|
|
BranchNumViews.value = InterfaceState[s][24]
|
|
BranchDRLevel.value = InterfaceState[s][25]
|
|
BranchOverRideBitmapSize.checked = InterfaceState[s][26]
|
|
BranchWidthOveride.value = InterfaceState[s][27]
|
|
BranchHeightOveride.value = InterfaceState[s][28]
|
|
|
|
try
|
|
(
|
|
Area = MasterObjData[s][3]
|
|
if Area == "BE" do GameArea.selection = 1
|
|
if Area == "JR" do GameArea.selection = 2
|
|
if Area == "PH" do GameArea.selection = 3
|
|
if Area == "IJ" do GameArea.selection = 4
|
|
if Area == "TO" do GameArea.selection = 5
|
|
if Area == "PL" do GameArea.selection = 6
|
|
if Area == "PV" do GameArea.selection = 7
|
|
if Area == "SH" do GameArea.selection = 8
|
|
if Area == "LA" do GameArea.selection = 9
|
|
if Area == "AS" do GameArea.selection = 10
|
|
if Area == "SU" do GameArea.selection = 11
|
|
) catch (
|
|
format "Area test failed...\n"
|
|
-- GameArea.selection = 7
|
|
)
|
|
|
|
if renderSeperate.checked then
|
|
(
|
|
CTrunk = MasterObjData[s][1]
|
|
CBranches = MasterObjData[s][2]
|
|
CTrunk = copy MasterObjData[s][1]
|
|
CTrunk.wirecolor = MasterObjData[s][1].wirecolor
|
|
CTrunk.mat = copy MasterObjData[s][1].mat
|
|
if MasterObjData[s][2] != undefined do
|
|
(
|
|
CBranches = copy MasterObjData[s][2]
|
|
CBranches.wirecolor = MasterObjData[s][2].wirecolor
|
|
CBranches.mat = copy CBranches.mat
|
|
)
|
|
) else (
|
|
format "MasterObjData[s]: %\n" MasterObjData[s]
|
|
CTrunk = copy MasterObjData[s][1]
|
|
try (CTrunk.wirecolor = MasterObjData[s][1].wirecolor) catch ()
|
|
CTrunk.mat = copy MasterObjData[s][1].mat
|
|
SingleObject = true
|
|
hide MasterObjData[s][1]
|
|
--else (
|
|
-- CTrunk = copy MasterObjData[s][1]
|
|
-- CTrunk.wirecolor = MasterObjData[s][1].wirecolor
|
|
-- CTrunk.mat = copy CTrunk.mat
|
|
-- CBranches = copy MasterObjData[s][2]
|
|
-- CBranches.wirecolor = CBranches.wirecolor
|
|
-- CBranches.mat = copy CBranches.mat
|
|
-- hide MasterObjData[s][1]
|
|
-- hide MasterObjData[s][2]
|
|
-- attach CTrunk CBranches
|
|
-- CBranches = undefined
|
|
-- AttachedTrunk = true
|
|
--)
|
|
)
|
|
|
|
if CTrunk != undefined then
|
|
(
|
|
for i = 1 to 2 do
|
|
(
|
|
for o in objects do hide o
|
|
if i == 1 do unhide CTrunk
|
|
if CBranches != undefined do
|
|
if i == 2 do unhide CBranches
|
|
|
|
if renderSeperate.checked and i == 2 then
|
|
NumVs = BranchNumViews.value as integer
|
|
else
|
|
NumVs = NumViews.value as integer
|
|
|
|
CObj = undefined
|
|
if i == 1 then
|
|
if CTrunk != undefined do
|
|
CObj = CTrunk
|
|
else
|
|
if CBranches != undefined do
|
|
CObj = CBranches
|
|
|
|
-- these arrays will hold the final scaled/cropped map data
|
|
FinalOpacities = #()
|
|
FinalTextures = #()
|
|
InTexNameArray = #()
|
|
OutTexNameArray = #()
|
|
InOpNameArray = #()
|
|
OutOpNameArray = #()
|
|
|
|
if CObj != undefined then
|
|
(
|
|
CWireColor = CObj.wirecolor
|
|
if (GenTrunk.checked and i == 1) or (GenBranches.checked and i == 2) do
|
|
(
|
|
status1.text = "Calculating object info..."
|
|
OriginalMat = copy CObj.mat
|
|
-- setup Area object info for tracking
|
|
AreaKey = ""
|
|
if GameArea.selection == 1 do (AreaKey = "BE")
|
|
if GameArea.selection == 2 do (AreaKey = "JR")
|
|
if GameArea.selection == 3 do (AreaKey = "PH")
|
|
if GameArea.selection == 4 do (AreaKey = "IJ")
|
|
if GameArea.selection == 5 do (AreaKey = "TO")
|
|
if GameArea.selection == 6 do (AreaKey = "PL")
|
|
if GameArea.selection == 7 do (AreaKey = "PV")
|
|
if GameArea.selection == 8 do (AreaKey = "SH")
|
|
if GameArea.selection == 9 do (AreaKey = "LA")
|
|
if GameArea.selection == 10 do (AreaKey = "AS")
|
|
if GameArea.selection == 11 do (AreaKey = "SU")
|
|
-- DL is the detail level
|
|
DL = (DRLevel.value as integer) as string
|
|
if renderSeperate.checked and i == 2 do
|
|
DL = (BranchDRLevel.value as integer) as string
|
|
-- initialize some arrays
|
|
BitMapArray = #()
|
|
OpacityMapArray = #()
|
|
DRObjectsArray = #()
|
|
-- Set the Background color to black
|
|
backgroundColor = (color 0 0 0)
|
|
-- grab and set the Ambient light color to what's specified in the interface
|
|
AmbientColor = AmbientCol.color
|
|
-- setup field of vision
|
|
fov = 10
|
|
CObjSize = (CObj.max - CObj.min)
|
|
-- create a cricle for the camera path
|
|
status1.text = "Calculating Camera..."
|
|
CameraPath = circle()
|
|
|
|
-- if center to base is checked, we determine the center of the lowest set of
|
|
-- vertices in the mesh (the bottom of the trunk) and set the x,y center position to that.
|
|
-- This way, we can make sure that the base of the trunk in each image view lies at the same position.
|
|
-- Otherwise, we just use the object center
|
|
if CenterToBase.checked then
|
|
if i == 2 then
|
|
(
|
|
ObjCenter = CObj.center
|
|
) else (
|
|
ObjCenter = trunkCenter CObj TrunkCenterThresh.value
|
|
ObjCenter = [ObjCenter.x, ObjCenter.y, CObj.center.z]
|
|
)
|
|
else
|
|
ObjCenter = CObj.center
|
|
|
|
CameraPath.pos = ObjCenter
|
|
rotate CameraPath 90 Z_Axis
|
|
theta = fov
|
|
offsetHeight = false
|
|
-- here, we find the largest distance of either the height,
|
|
-- or the distance between the x,y coordinates of the .min and .max (thus the maximun diameter)
|
|
if (distance [CObj.max.x,CObj.max.y] [CObj.min.x,CObj.min.y]) > (CObj.max.z - CObj.min.z) then
|
|
(
|
|
d = (distance [CObj.max.x,CObj.max.y] [CObj.min.x,CObj.min.y])
|
|
offsetHeight = true
|
|
if debug do format "Using objects maximum DIAMETER for largest dimension...\n"
|
|
) else (
|
|
d = (CObj.max.z - CObj.min.z)
|
|
if debug do format "Using objects maximum HEIGHT for largest dimension...\n"
|
|
)
|
|
|
|
-- setup the camera and it's position so that the object lies square in it's viewport
|
|
h = (d / (2 * sin(theta / 2)))
|
|
x = h * (cos(theta))
|
|
NewCamera = targetCamera()
|
|
NewCamera.fov = fov
|
|
NewCamera.target = targetObject()
|
|
NewCamera.target.pos = ObjCenter
|
|
NewDir = normalize (NewCamera.pos - NewCamera.target.pos)
|
|
NewCamera.pos = NewCamera.target.pos + NewDir * x
|
|
CameraDist = distance NewCamera.pos Newcamera.target.pos
|
|
CameraPath.radius = CameraDist
|
|
NewCamera.pos.controller = path()
|
|
NewCamera.pos.controller.path = CameraPath
|
|
|
|
BoxDimension = ((distance NewCamera.pos NewCamera.target.pos) * (tan(fov * 0.5))) * 2
|
|
-- could be used as scale factor???
|
|
fScale = [BoxDimension, BoxDimension]
|
|
|
|
-- if we're using the largest diameter of the object, we need to change the object height so
|
|
-- that the base of the new detail reduced object matches the base of th object itself.
|
|
if (offsetHeight == true) and (i != 2) do
|
|
(
|
|
Objheight = (CObj.max.z - CObj.min.z) * 0.5
|
|
ViewHeight = (((distance NewCamera.pos NewCamera.target.pos) * (tan(fov * 0.5))) * 2) * 0.5
|
|
HeightOffset = abs(Objheight - ViewHeight)
|
|
CameraPath.pos = [CameraPath.pos.x, CameraPath.pos.y, CObj.center.z]
|
|
--CameraPath.pos = [CameraPath.pos.x, CameraPath.pos.y, CameraPath.pos.z + HeightOffset]
|
|
NewCamera.target.pos = CameraPath.pos
|
|
if debug do format "Camera Offset height:%\n" HeightOffset
|
|
)
|
|
|
|
-- set the camera height to be at eye level from the base of the tree
|
|
-- eye level is 1.70 Meters
|
|
if CameraAtEyeHeight.checked and i == 1 do
|
|
(
|
|
newCameraHeight = (CObj.center.z - (CObj.max.z - CObj.min.z) * 0.5) + 1.70
|
|
CameraPath.pos = [CameraPath.pos.x, CameraPath.pos.y, newCameraHeight]
|
|
)
|
|
|
|
if BranchCameraAtEyeHeight.checked and i == 2 do
|
|
(
|
|
-- we base eye height for the branches off the dimensions of the trunk
|
|
newCameraHeight = (CTrunk.center.z - (CTrunk.max.z - CTrunk.min.z) * 0.5) + 1.65
|
|
CameraPath.pos = [CameraPath.pos.x, CameraPath.pos.y, newCameraHeight]
|
|
)
|
|
|
|
-- setup the animation of the camera about the path based on the number of views the user wants to use
|
|
deletekeys NewCamera.pos.controller #allkeys
|
|
c = NewCamera.pos.controller
|
|
addNewKey c 0
|
|
addNewKey c NumVs
|
|
animate on
|
|
(
|
|
at time 0 c.percent = 0.0
|
|
at time NumVs c.percent = 100.0
|
|
)
|
|
status1.text = "Generating Light..."
|
|
-- makes sure any and all lights are deleted
|
|
for l in lights do delete l
|
|
CLight = freespot()
|
|
CLight.dir = SunArray[GameArea.selection]
|
|
CLight.HotSpot = 60
|
|
CLight.color = (color 255 255 255)
|
|
CLight.Multiplier = CMult.value
|
|
SunDir = CLight.dir
|
|
theta = CLight.HotSpot
|
|
d = distance CObj.max CObj.min
|
|
x = (d / (2 * sin(theta / 2)))
|
|
CLight.pos = (CObj.center + SunDir * 1000)
|
|
|
|
if i == 1 and isPrelit.checked do
|
|
(
|
|
ambientColor = (color 255 255 255)
|
|
lts = for l in lights collect l
|
|
delete lts
|
|
)
|
|
|
|
status1.text = "Calculating Bitmap info and Materials..."
|
|
-- determine the bitmap size
|
|
BitMapSizeValue = ((PixelsPerMeter.value as float) * BoxDimension) as integer
|
|
if BitMapSizeValue > 300 do BitMapSizeValue = 300
|
|
|
|
if debug do format "Rendered map dimension: %\n" BitMapSizeValue
|
|
|
|
status1.text = "Rendering texture maps..."
|
|
-- Render all the texture maps
|
|
for j = 1 to NumVs do
|
|
(
|
|
Append BitMapArray (render camera:NewCamera outputwidth:BitMapSizeValue outputheight:BitMapSizeValue frame:j vfb:off)
|
|
if debug do display BitMaparray[j]
|
|
)
|
|
|
|
if classof CObj.mat == StandardMaterial do
|
|
(
|
|
CObj.mat.diffuse = (color 255 255 255)
|
|
CObj.mat.DiffuseMapEnable = false
|
|
CObj.mat.BumpMapEnable = false
|
|
CObj.mat.shinestrength = 0.0
|
|
CObj.mat.selfIllum = 100
|
|
)
|
|
|
|
if classof CObj.mat == multiMaterial do
|
|
(
|
|
ns = CObj.mat.numsubs
|
|
for j = 1 to ns do
|
|
(
|
|
CObj.mat[j].diffuse = (color 255 255 255)
|
|
CObj.mat[j].DiffuseMapEnable = false
|
|
CObj.mat[j].BumpMapEnable = false
|
|
CObj.mat[j].shinestrength = 0.0
|
|
CObj.mat[j].selfIllum = 100
|
|
)
|
|
)
|
|
|
|
status1.text = "Rendering opacity maps..."
|
|
-- render all the opacity maps
|
|
for j = 1 to NumVs do
|
|
(
|
|
Append OpacityMapArray (render camera:NewCamera outputwidth:BitMapSizeValue outputheight:BitMapSizeValue frame:j vfb:off)
|
|
if debug do display OpacityMaparray[j]
|
|
)
|
|
|
|
CObj.mat = OriginalMat
|
|
|
|
if classof CObj.mat == StandardMaterial do
|
|
(
|
|
CObj.mat.DiffuseMapEnable = true
|
|
CObj.mat.BumpMapEnable = true
|
|
CObj.mat.shinestrength = 0.0
|
|
CObj.mat.selfIllum = 0.0
|
|
)
|
|
|
|
if classof CObj.mat == multiMaterial do
|
|
(
|
|
ns = CObj.mat.numsubs
|
|
for j = 1 to ns do
|
|
(
|
|
CObj.mat[j].DiffuseMapEnable = true
|
|
CObj.mat[j].BumpMapEnable = true
|
|
CObj.mat[j].shinestrength = 0.0
|
|
CObj.mat[j].selfIllum = 0.0
|
|
)
|
|
)
|
|
|
|
CNamePrefix = ""
|
|
CNameSuffix = ""
|
|
|
|
for j = 1 to CObj.name.count do
|
|
if CObj.name[j] == "~" do
|
|
MagicIndex = j
|
|
if MagicIndex != undefined then
|
|
(
|
|
CNamePrefix = substring CObj.name 1 (MagicIndex - 1)
|
|
CNameSuffix = ((substring CObj.name (MagicIndex + 1) 3) + ((DRLevel.value as integer) as string))
|
|
) else (
|
|
for j = 1 to CObj.name.count do
|
|
if CObj.name[j] == "-" do
|
|
MagicIndex = j
|
|
|
|
if magicIndex == undefined do
|
|
MagicIndex = CObj.name.count
|
|
|
|
CNamePrefix = substring CObj.name 1 (MagicIndex - 1)
|
|
CNameSuffix = ((substring CObj.name (MagicIndex + 1) 3) + ((DRLevel.value as integer) as string))
|
|
)
|
|
|
|
ProgressStart "Generating Views..."
|
|
for t = 1 to NumVs do
|
|
(
|
|
at time t
|
|
(
|
|
ProgressUpdate ((t/NumVs as float) * 100)
|
|
-- ************************************************************
|
|
-- ** Process the bitmaps**************************************
|
|
-- ************************************************************
|
|
if i == 2 and SplitMethod.checked do ()
|
|
-- process the bitmaps for size/scale
|
|
status1.text = "Processing Bitmaps..."
|
|
iStartWidth = OpacityMapArray[t].width
|
|
iStartHeight = OpacityMapArray[t].height
|
|
|
|
BitmapInfo = ThresholdBitmap OpacityMapArray[t] (OpacityThresh.value as integer)
|
|
-- bitmapInfo = #(map, startpoint, new map size)
|
|
if debug do
|
|
(
|
|
format "%\n" BitmapInfo
|
|
display OpacityMapArray[t]
|
|
)
|
|
-- calculate the width and height scalar values for the geometry based on the new cropped areas
|
|
WidthScalar = BitmapInfo[3].x as float / OpacityMapArray[t].width as float
|
|
HeightScalar = BitmapInfo[3].y as float / OpacityMapArray[t].height as float
|
|
|
|
-- crop the bitmaps
|
|
OpacityMapArray[t] = CropBitmap BitmapInfo[1] BitmapInfo[2] [(BitmapInfo[3].x), BitmapInfo[3].y]
|
|
BitMapArray[t] = CropBitmap BitmapArray[t] BitmapInfo[2] [(BitmapInfo[3].x), BitmapInfo[3].y]
|
|
|
|
iCropWidth = OpacityMapArray[t].width
|
|
iCropHeight = OpacityMapArray[t].height
|
|
|
|
if i == 2 and SplitMethod.checked then
|
|
(
|
|
w1o = ((iStartWidth / 2) - BitmapInfo[2].x) as integer
|
|
OpacityMapArray[t] = CropBitmap OpacityMapArray[t] [w1o,0] [(iCropWidth - w1o), iCropHeight]
|
|
BitMapArray[t] = CropBitmap BitMapArray[t] [w1o,0] [(iCropWidth - w1o), iCropHeight]
|
|
NewBitMapWidth = (BitmapInfo[3].x / 2)
|
|
NewBitMapHeight = BitmapInfo[3].y
|
|
) else (
|
|
NewBitMapWidth = BitmapInfo[3].x
|
|
NewBitMapHeight = BitmapInfo[3].y
|
|
)
|
|
|
|
-- Extra checking for illegal map sizes (> 256, < 8)
|
|
if NewBitMapHeight > 256 do NewBitMapHeight = 256
|
|
if NewBitMapWidth > 256 do NewBitMapWidth = 256
|
|
if NewBitMapHeight < 8 do NewBitMapHeight = 8
|
|
if NewBitMapWidth < 8 do NewBitMapWidth = 8
|
|
|
|
if RescaleBitmaps.checked do
|
|
(
|
|
reCalc = true
|
|
if i == 1 and OverRideBitmapSize.checked do
|
|
(
|
|
NewBitMapWidth = TrunkWidthOveride.value
|
|
NewBitMapHeight = TrunkHeightOveride.value
|
|
reCalc = false
|
|
)
|
|
|
|
if i == 2 and BranchOverRideBitmapSize.checked do
|
|
(
|
|
NewBitMapWidth = BranchWidthOveride.value
|
|
NewBitMapHeight = BranchHeightOveride.value
|
|
reCalc = false
|
|
)
|
|
|
|
if reCalc == true do
|
|
(
|
|
-- calculate the new bitmap dimensions to the nearest power of two size
|
|
NewBitMapWidth = NearPowOfTwo NewBitMapWidth sizeMaps.state
|
|
NewBitMapHeight = NearPowOfTwo NewBitMapHeight sizeMaps.state
|
|
NSize = (PowOfLimit NewBitMapWidth NewBitMapHeight)
|
|
NewBitMapWidth = NSize.x as integer
|
|
NewBitMapHeight = NSize.y as integer
|
|
)
|
|
|
|
if AutoDetermineMapSizes.checked do
|
|
(
|
|
if debug do format "Auto Determining Map Sizes...\n"
|
|
iHt = (CObj.max.z - CObj.min.z)
|
|
-- figure out the predetermined height of the map
|
|
if DRLevel.value == 1 then
|
|
(
|
|
if iHt >= 0 and iHt <= 1 do NewBitMapHeight = 64
|
|
if iHt > 1 and iHt <= 5 do NewBitMapHeight = 128
|
|
if iHt > 5 do NewBitMapHeight = 256
|
|
if debug do format "DRLevel:% Bitmap height: %\n" DRLevel.value NewBitMapHeight
|
|
) else (
|
|
-- Detail Levels > 2
|
|
if iHt >= 0 and iHt <= 1 do NewBitMapHeight = 32
|
|
if iHt > 1 and iHt <= 5 do NewBitMapHeight = 64
|
|
if iHt > 5 do NewBitMapHeight = 128
|
|
if debug do format "DRLevel:% Bitmap height: %\n" DRLevel.value NewBitMapHeight
|
|
)
|
|
-- now determine the width
|
|
iWth = (distance [CObj.max.x, CObj.max.y] [CObj.min.x, CObj.min.y])
|
|
NewBitMapWidth = ((iWth * NewBitMapHeight) / iHt) as integer
|
|
if debug do format "iHt:%\tiWd:%\tbHt:%\tbWd:%\n" iHt iWth NewBitMapHeight NewBitMapWidth
|
|
NewBitMapWidth = NearPowOfTwo NewBitMapWidth 2 -- always go lower
|
|
NSize = (PowOfLimit NewBitMapWidth NewBitMapHeight)
|
|
NewBitMapWidth = NSize.x as integer
|
|
NewBitMapHeight = NSize.y as integer
|
|
if debug do format "BitMap Size calculated to be %\n" NSize
|
|
)
|
|
)
|
|
|
|
if debug do format "Initial BitmapSize: %\t%\nNew Bitmap size: %\t%\n" BitmapInfo[3].x BitmapInfo[3].y NewBitMapWidth NewBitMapHeight
|
|
|
|
-- set the filenames...
|
|
FinalOpName = (WorkingFolder + CNamePrefix + t as string + "~" + CNameSuffix + "o8.bmp")
|
|
FinalTexName = (WorkingFolder + CNamePrefix + t as string + "~" + CNameSuffix + "t2.bmp")
|
|
InTexName = (WorkingFolder + "t" + t as string + ".bmp")
|
|
OutTexName = (WorkingFolder + "t_" + t as string + ".bmp")
|
|
InOpName = (WorkingFolder + "o" + t as string + ".bmp")
|
|
OutOpName = (WorkingFolder + "o_" + t as string + ".bmp")
|
|
|
|
if i == 2 and SplitMethod.checked then
|
|
(
|
|
NewOp = bitmap (NewBitMapWidth / 2) NewBitMapHeight
|
|
NewTex = bitmap (NewBitMapWidth / 2) NewBitMapHeight
|
|
) else (
|
|
NewOp = bitmap NewBitMapWidth NewBitMapHeight
|
|
NewTex = bitmap NewBitMapWidth NewBitMapHeight
|
|
)
|
|
|
|
try
|
|
(
|
|
copy OpacityMapArray[t] NewOp
|
|
copy BitMapArray[t] NewTex
|
|
) catch (
|
|
MessageBox "Something fucked up.\nGo get Kyle."
|
|
)
|
|
|
|
-- Start the Graham's Scan
|
|
-- Identify all the edge pixels
|
|
status1.text = "Identifying Edges...."
|
|
p = IdentifyEdges NewOp YIncrement.value
|
|
|
|
-- add some random jitter to the array of points so the angle array will sort properly
|
|
aj = AngleJitter.value
|
|
for j = 1 to p.count do
|
|
(
|
|
if p[j].x == 0 do (p[j].x += (random 0 aj))
|
|
if p[j].y == 0 do (p[j].y += (random 0 aj))
|
|
if p[j].x == NewOp.width do (p[j].x += (random -aj 0))
|
|
if p[j].y == NewOp.height do (p[j].y += (random -aj 0))
|
|
if p[j].x < NewOp.width and p[j].x > 0 do (p[j].x += (random -aj aj))
|
|
if p[j].y < NewOp.height and p[j].y > 0 do (p[j].y += (random -aj aj))
|
|
)
|
|
|
|
-- do the Graham Scan
|
|
status1.text = "Calculating convex hull..."
|
|
Hullpoints = GrahamScan p
|
|
-- remove the jitter to the array of points are integers again
|
|
for j = 1 to Hullpoints.count do
|
|
(Hullpoints[j] = [(rnd Hullpoints[j].x), (rnd Hullpoints[j].y)])
|
|
status1.text = "Reducing Points..."
|
|
HullPoints = pruneClosePoints HullPoints PrunePointsThreshold.value
|
|
|
|
-- set the new filenames
|
|
NewOp.filename = InOpName
|
|
NewTex.filename = InTexName
|
|
|
|
-- Delete the files (if they're already there)
|
|
DeleteFile NewOp.filename
|
|
DeleteFile NewTex.filename
|
|
|
|
-- and save them...
|
|
save NewTex
|
|
save NewOp
|
|
|
|
status1.text = "Starting Alchemy..."
|
|
-- Process Maps via Alchemy
|
|
doscommand ("alchemy -w -o -b " + InOpName + " " + OutOpName)
|
|
doscommand ("alchemy -w -o " + InTexName + " " + OutTexName)
|
|
|
|
-- doscommand ("alchemy -w -o -b -X" + NewBitMapWidth as string + " -Y" + NewBitMapHeight as string + " " + InOpName + " " + OutOpName)
|
|
-- doscommand ("alchemy -w -o -X" + NewBitMapWidth as string + " -Y" + NewBitMapHeight as string + " " + InTexName + " " + OutTexName)
|
|
if debug do format "Alchemy Done!...\nProcessing Bitmaps Finished!\n"
|
|
|
|
-- Delete files that may already be there
|
|
deleteFile FinalOpName
|
|
deleteFile FinalTexName
|
|
|
|
-- Copy the processed bitmaps to their final name/location
|
|
copyFile OutOpName FinalOpName
|
|
copyFile OutTexName FinalTexName
|
|
|
|
-- ************************************************************
|
|
-- ** Create the new mesh *************************************
|
|
-- ************************************************************
|
|
-- calculate the new uv's for Hullpoints
|
|
status1.text = "Calculating Texture Vertices..."
|
|
minX = HullPoints[1].x
|
|
maxX = HullPoints[1].x
|
|
minY = HullPoints[1].y
|
|
maxY = HullPoints[1].y
|
|
for i = 1 to HullPoints.count do
|
|
(
|
|
if HullPoints[i].x > maxX do maxX = HullPoints[i].x
|
|
if HullPoints[i].x < minX do minX = HullPoints[i].x
|
|
if HullPoints[i].y > maxY do maxY = HullPoints[i].y
|
|
if HullPoints[i].y < minY do minY = HullPoints[i].y
|
|
)
|
|
|
|
iWidth = maxX - minX
|
|
iHeight = maxY - minY
|
|
iDimension = [iWidth, iHeight]
|
|
iCorner = [minX, minY]
|
|
|
|
du = 1.0 / iWidth
|
|
dv = 1.0 / iHeight
|
|
|
|
-- flip all the y points
|
|
for j = 1 to Hullpoints.count do (Hullpoints[j].y = iHeight - Hullpoints[j].y)
|
|
|
|
TVertArray = #()
|
|
for j = 1 to Hullpoints.count do
|
|
(
|
|
Tvert = [(HullPoints[j].x * du), (HullPoints[j].y * dv),1.0]
|
|
append TVertArray Tvert
|
|
)
|
|
|
|
BoxDimension = ((distance NewCamera.pos NewCamera.target.pos) * (tan(fov * 0.5))) * 2
|
|
|
|
if i == 2 and SplitMethod.checked then
|
|
PixelSize = (BoxDimension as float / iCropWidth)
|
|
else
|
|
PixelSize = (BoxDimension as float / BitMapSizeValue)
|
|
|
|
-- PixelSize = (BoxDimension as float / BitMapSizeValue as float)
|
|
if debug do format "PixelSize:%\n" PixelSize
|
|
|
|
-- calculate the width and height offsets for the new geometry
|
|
w1 = BitmapInfo[2].x
|
|
w2 = BitmapInfo[1].width - (w1 + BitmapInfo[3].x)
|
|
AvgFreeWidth = (BitmapInfo[1].width - BitmapInfo[3].x) * 0.5
|
|
if w2 >= w1 then
|
|
ObjectOffsetW = (AvgFreeWidth - w1) * PixelSize
|
|
else
|
|
ObjectOffsetW = -(AvgFreeWidth - w2) * PixelSize
|
|
|
|
if i == 2 and SplitMethod.checked do
|
|
ObjectOffsetW = (iStartWidth - iCropWidth) * PixelSize
|
|
|
|
h1 = BitmapInfo[2].y
|
|
h2 = BitmapInfo[1].height - (h1 + BitmapInfo[3].y)
|
|
AvgFreeHeight = (BitmapInfo[1].height - BitmapInfo[3].y) * 0.5
|
|
|
|
if h2 >= h1 then
|
|
ObjectOffsetV = (AvgFreeHeight - h1) * PixelSize
|
|
else
|
|
ObjectOffsetV = -(AvgFreeHeight - h2) * PixelSize
|
|
|
|
if debug do
|
|
(
|
|
format "w1:% w2:% h1:% h2:%\n" w1 w2 h1 h2
|
|
format "Height Offset:%\nWidth Offset:%\nAvg Free: % %\n" ObjectOffsetV ObjectOffsetW AvgFreeWidth AvgFreeHeight
|
|
)
|
|
|
|
-- width and height of the object in 3space
|
|
NewHeight = BoxDimension as float * HeightScalar
|
|
if i == 2 and SplitMethod.checked then
|
|
NewWidth = (BoxDimension as float * WidthScalar) / 2
|
|
else
|
|
NewWidth = (BoxDimension as float * WidthScalar)
|
|
|
|
-- make the box
|
|
b = box()
|
|
b.width = NewWidth
|
|
b.height = BoxDimension
|
|
b.length = NewHeight
|
|
b.pos = NewCamera.target.pos
|
|
b.dir = -NewCamera.dir
|
|
if debug do format "Camera Dir vector @ %: %\n" t -NewCamera.dir
|
|
b.mapcoords = true
|
|
convertToMesh b
|
|
-- delete the verts off the box that we don't need.
|
|
for j = 1 to 4 do deleteVert b b.numverts
|
|
if NewCamera.dir.x < 0.0 do
|
|
in coordsys local rotate b 180 z_axis
|
|
in coordsys local rotate b 180 z_axis
|
|
if SplitMethod.checked and i == 2 then
|
|
in coordsys local move b [-(NewWidth * 0.5), -ObjectOffsetV, 0]
|
|
else
|
|
in coordsys local move b [ObjectOffsetW, ObjectOffsetV, 0]
|
|
convertToMesh b
|
|
|
|
-- Calculate the new points in 3space via the uv coordinates
|
|
P0 = getVert b 2
|
|
P1 = getVert b 1
|
|
P2 = getVert b 4
|
|
P3 = getVert b 3
|
|
|
|
fVertArray = #()
|
|
|
|
for j = 1 to TVertArray.count do
|
|
(
|
|
Px = (P0.x + (TVertArray[j].x * (P1.x - P0.x)) + (TVertArray[j].y * (P2.x - P0.x)))
|
|
Py = (P0.y + (TVertArray[j].x * (P1.y - P0.y)) + (TVertArray[j].y * (P2.y - P0.y)))
|
|
Pz = (P0.z + (TVertArray[j].x * (P1.z - P0.z)) + (TVertArray[j].y * (P2.z - P0.z)))
|
|
append fVertArray [Px,Py,Pz]
|
|
)
|
|
iFaceArray = #([1,2,3])
|
|
for i = 3 to (Hullpoints.count - 1) do (append iFaceArray [1,i,i+1])
|
|
-- construct the mesh
|
|
delete b
|
|
b = mesh vertices:fVertArray faces:iFaceArray
|
|
if b.numverts > 16 do (format "Warning: more than 16 verts detected in convex hull object... please check and regenerate if needed...\n")
|
|
-- apply the texture coordinates
|
|
addmodifier b (UVWMap())
|
|
convertToMesh b
|
|
for i = 1 to b.numfaces do
|
|
(
|
|
iFace = getFace b i
|
|
iTFace = getTVFace b i
|
|
setTvert b iTFace.x (TVertArray[iFace.x])
|
|
setTvert b iTFace.y (TVertArray[iFace.y])
|
|
setTvert b iTFace.z (TVertArray[iFace.z])
|
|
)
|
|
-- Set the Edge visibility
|
|
for i = 1 to b.numfaces do
|
|
(
|
|
if i == 1 do setEdgeVis b i 3 off
|
|
if i == b.numfaces do setEdgeVis b i 1 off
|
|
if i > 1 and i < b.numfaces do
|
|
(
|
|
SetEdgeVis b i 1 off
|
|
SetEdgeVis b i 3 off
|
|
)
|
|
)
|
|
update b
|
|
|
|
df = #()
|
|
for i = 1 to b.numfaces do
|
|
(
|
|
Cface = getface b i
|
|
n = 4
|
|
NewX = rndP3 (getvert b Cface.x) n
|
|
NewY = rndP3 (getvert b Cface.y) n
|
|
NewZ = rndP3 (getvert b Cface.z) n
|
|
if (Thresh NewX NewY 0.001) do
|
|
if findItem df i == 0 do (append df i)
|
|
|
|
if (Thresh NewX NewZ 0.001) do
|
|
if findItem df i == 0 do (append df i)
|
|
|
|
if (Thresh NewZ NewY 0.001) do
|
|
if findItem df i == 0 do (append df i)
|
|
|
|
-- check for a degenerate normal
|
|
if (GetFaceNormal b i) == [0,0,0] do
|
|
if findItem df i == 0 do (append df i)
|
|
)
|
|
|
|
if df.count > 0 do
|
|
(
|
|
format "found degenerate polygons... deleting them\n"
|
|
for i = df.count to 1 by -1 do
|
|
deleteFace b df[i]
|
|
update b
|
|
)
|
|
|
|
-- Check for Stray Vertices
|
|
StrayVertArray = (for i = 1 to b.numverts collect i)
|
|
UsedVerts = #()
|
|
NewVertSelection = #()
|
|
|
|
for i = 1 to b.numfaces do
|
|
(
|
|
CFace = (getface b i)
|
|
if (findItem UsedVerts CFace.x) == 0 do (append UsedVerts CFace.x)
|
|
if (findItem UsedVerts CFace.y) == 0 do (append UsedVerts CFace.y)
|
|
if (findItem UsedVerts CFace.z) == 0 do (append UsedVerts CFace.z)
|
|
)
|
|
|
|
for i = 1 to StrayVertArray.count do
|
|
if (findItem UsedVerts i) == 0 do (append NewVertSelection i)
|
|
|
|
if NewVertSelection.count > 0 then
|
|
(
|
|
format "Stray vertices were found... deleting them\n"
|
|
for i = NewVertSelection.count to 1 by -1 do
|
|
deleteVert b NewVertSelection[i]
|
|
update b
|
|
)
|
|
|
|
if DRLevel.value == 1 then b.wirecolor = scaleColor CWireColor 0.75
|
|
if DRLevel.value == 2 then b.wirecolor = scaleColor CWireColor 0.65
|
|
if DRLevel.value == 3 then b.wirecolor = scaleColor CWireColor 0.50
|
|
if DRLevel.value == 4 then b.wirecolor = scaleColor CWireColor 0.40
|
|
-- ************************************************************
|
|
-- ** Generate a new material *********************************
|
|
-- ************************************************************
|
|
-- make sure all face IDs are set to 1
|
|
status1.text = "Building a new material..."
|
|
for j = 1 to b.numfaces do setFaceMatID b j 1
|
|
NMat = standardMaterial()
|
|
-- give it a random color
|
|
NMat.diffuse = random (color 20 20 20) (color 220 220 220)
|
|
NMat.diffuseMap = bitmaptexture()
|
|
NMat.OpacityMap = bitmaptexture()
|
|
-- specify the bitmap names
|
|
NMat.diffuseMap.filename = FinalTexName
|
|
NMat.OpacityMap.filename = FinalOpName
|
|
NMat.shinestrength = 0.0
|
|
NMat.name = substring OutTexName 1 (OutTexName.count - 3)
|
|
NMat.selfIllum = 100
|
|
b.mat = NMat
|
|
append DRObjectsArray b
|
|
if debug do format "Finished building new material!\n"
|
|
)
|
|
)
|
|
ProgressEnd()
|
|
-- Attach the detail reduced objects together
|
|
for j = DRObjectsArray.count to 2 by -1 do
|
|
attach DRObjectsArray[1] DRObjectsArray[j]
|
|
DRObject = DRObjectsArray[1]
|
|
DRObject.mat.name = (CObj.name + "dr")
|
|
|
|
if i == 1 then
|
|
DRL = DRLevel.value as integer
|
|
else
|
|
DRL = BranchDRLevel.value as integer
|
|
|
|
DRObject.name = ("$" + (substring CObj.name 1 (CObj.name.count - 4)) + DRL as string + "-00")
|
|
DRObject.pivot = CObj.pivot
|
|
f = for i = 1 to DRObject.numfaces collect i
|
|
setFaceSelection DRObject f
|
|
if flip != undefined do
|
|
if flip then CopyAndFlipFaces DRObject
|
|
try (
|
|
if (i != 1) or (isPrelit.checked == false) do
|
|
(
|
|
delete CLight
|
|
CLight = undefined
|
|
)
|
|
) catch ()
|
|
if debug != true do
|
|
(
|
|
delete NewCamera
|
|
NewCamera = undefined
|
|
delete CameraPath
|
|
CameraPath = undefined
|
|
)
|
|
CObj.mat = OriginalMat
|
|
)
|
|
) else (
|
|
if renderSeperate.checked do
|
|
MessageBox "No Objects Defined!"
|
|
)
|
|
gc() -- collect some garbage
|
|
status1.text = ""
|
|
)
|
|
-- Lonnie, comment the next two lines out "--"
|
|
-- if SingleObject == true do
|
|
-- delete CTrunk
|
|
delete CTrunk
|
|
if CBranches != undefined do delete CBranches
|
|
-- unhide everything at the end...
|
|
for o in objects do unhide o
|
|
CTrunk = CBranches = undefined
|
|
status1.text = ""
|
|
) else (
|
|
MessageBox "You must initialize the objects first"
|
|
)
|
|
)
|
|
messageBox "Complete"
|
|
)
|
|
|
|
|
|
-- *******************************************************************************************************
|
|
-- ****************** ***********************
|
|
-- ****************** Generate Shadow Object ***********************
|
|
-- ****************** ***********************
|
|
-- *******************************************************************************************************
|
|
|
|
on CreateShadowObject pressed do
|
|
(
|
|
for s = 1 to InterfaceState.count do
|
|
(
|
|
BatchList.selection = s
|
|
renderSeperate.checked = InterfaceState[s][1]
|
|
CenterToBase.checked = InterfaceState[s][2]
|
|
TrunkCenterThresh.value = InterfaceState[s][3]
|
|
OpacityThresh.value = InterfaceState[s][4]
|
|
RescaleBitmaps.checked = InterfaceState[s][5]
|
|
sizeMaps.state = InterfaceState[s][6]
|
|
PixelsPerMeter.value = InterfaceState[s][7]
|
|
YIncrement.value = InterfaceState[s][8]
|
|
PrunePointsThreshold.value = InterfaceState[s][9]
|
|
AngleJitter.value = InterfaceState[s][10]
|
|
GenTrunk.checked = InterfaceState[s][11]
|
|
CameraAtEyeHeight.checked = InterfaceState[s][12]
|
|
isPrelit.checked = InterfaceState[s][13]
|
|
BitMapSize.value = InterfaceState[s][14]
|
|
NumViews.value = InterfaceState[s][15]
|
|
DRLevel.value = InterfaceState[s][16]
|
|
OverRideBitmapSize.checked = InterfaceState[s][17]
|
|
TrunkWidthOveride.value = InterfaceState[s][18]
|
|
TrunkHeightOveride.value = InterfaceState[s][19]
|
|
GenBranches.checked = InterfaceState[s][20]
|
|
BranchCameraAtEyeHeight.checked = InterfaceState[s][21]
|
|
SplitMethod.checked = InterfaceState[s][22]
|
|
BranchBitMapSize.value = InterfaceState[s][23]
|
|
BranchNumViews.value = InterfaceState[s][24]
|
|
BranchDRLevel.value = InterfaceState[s][25]
|
|
BranchOverRideBitmapSize.checked = InterfaceState[s][26]
|
|
BranchWidthOveride.value = InterfaceState[s][27]
|
|
BranchHeightOveride.value = InterfaceState[s][28]
|
|
|
|
Area = MasterObjData[s][3]
|
|
if Area == "BE" do GameArea.selection = 1
|
|
if Area == "JR" do GameArea.selection = 2
|
|
if Area == "PH" do GameArea.selection = 3
|
|
if Area == "IJ" do GameArea.selection = 4
|
|
if Area == "TO" do GameArea.selection = 5
|
|
if Area == "PL" do GameArea.selection = 6
|
|
if Area == "PV" do GameArea.selection = 7
|
|
if Area == "SH" do GameArea.selection = 8
|
|
if Area == "LA" do GameArea.selection = 9
|
|
if Area == "AS" do GameArea.selection = 10
|
|
if Area == "SU" do GameArea.selection = 11
|
|
|
|
if renderSeperate.checked then
|
|
(
|
|
CTrunk = MasterObjData[s][1]
|
|
CTrunk.wirecolor = MasterObjData[s][1].wirecolor
|
|
CBranches = MasterObjData[s][2]
|
|
CTrunk = copy MasterObjData[s][1]
|
|
CTrunk.mat = copy MasterObjData[s][1].mat
|
|
if MasterObjData[s][2] != undefined do
|
|
(
|
|
CBranches = copy MasterObjData[s][2]
|
|
CBranches.wirecolor = MasterObjData[s][2].wirecolor
|
|
CBranches.mat = copy CBranches.mat
|
|
)
|
|
) else (
|
|
CTrunk = MasterObjData[s][1]
|
|
CTrunk.wirecolor = MasterObjData[s][1].wirecolor
|
|
CBranches = MasterObjData[s][2]
|
|
if CBranches == undefined then
|
|
(
|
|
CTrunk = copy MasterObjData[s][1]
|
|
CTrunk.wirecolor = MasterObjData[s][1].wirecolor
|
|
CTrunk.mat = copy MasterObjData[s][1].mat
|
|
SingleObject = true
|
|
hide MasterObjData[s][1]
|
|
) else (
|
|
CTrunk = copy MasterObjData[s][1]
|
|
CTrunk.wirecolor = MasterObjData[s][1].wirecolor
|
|
CTrunk.mat = copy CTrunk.mat
|
|
CBranches = copy MasterObjData[s][2]
|
|
CBranches.wirecolor = MasterObjData[s][2].wirecolor
|
|
CBranches.mat = copy CBranches.mat
|
|
hide MasterObjData[s][1]
|
|
hide MasterObjData[s][2]
|
|
attach CTrunk CBranches
|
|
CBranches = undefined
|
|
AttachedTrunk = true
|
|
)
|
|
)
|
|
|
|
if CTrunk != undefined then
|
|
(
|
|
for i = 1 to 2 do
|
|
(
|
|
for o in objects do hide o
|
|
if i == 1 do unhide CTrunk
|
|
if CBranches != undefined do
|
|
if i == 2 do unhide CBranches
|
|
|
|
if renderSeperate.checked and i == 2 then
|
|
NumVs = BranchNumViews.value as integer
|
|
else
|
|
NumVs = NumViews.value as integer
|
|
|
|
CObj = undefined
|
|
if i == 1 then
|
|
if CTrunk != undefined do
|
|
CObj = CTrunk
|
|
else
|
|
if CBranches != undefined do
|
|
CObj = CBranches
|
|
|
|
if i == 1 and CBranches != undefined then
|
|
(
|
|
-- this is for the trunk
|
|
b = copy CObj
|
|
r = SunArray[GameArea.selection]
|
|
r = normalize [r.x, r.y, 0]
|
|
r = ray [0,0,0] r
|
|
FlattenObject b r
|
|
addmodifier b (UVWMap())
|
|
convertToMesh b
|
|
b.mat = standardMaterial()
|
|
b.name = ("$" + (substring CObj.name 1 (CObj.name.count - 4)) + "5-00")
|
|
) else (
|
|
if i == 1 do (CObj = CTrunk)
|
|
-- these arrays will hold the final scaled/cropped map data
|
|
FinalOpacities = #()
|
|
FinalTextures = #()
|
|
InTexNameArray = #()
|
|
OutTexNameArray = #()
|
|
InOpNameArray = #()
|
|
OutOpNameArray = #()
|
|
|
|
if CObj != undefined then
|
|
(
|
|
if (GenBranches.checked and (i == 2)) or ((i == 1) and (CObj == CTrunk)) do
|
|
(
|
|
status1.text = "Calculating object information..."
|
|
cw = CObj.wirecolor
|
|
OriginalMat = copy CObj.mat
|
|
-- setup Area object info for tracking
|
|
AreaKey = ""
|
|
if GameArea.selection == 1 do (AreaKey = "BE")
|
|
if GameArea.selection == 2 do (AreaKey = "JR")
|
|
if GameArea.selection == 3 do (AreaKey = "PH")
|
|
if GameArea.selection == 4 do (AreaKey = "IJ")
|
|
if GameArea.selection == 5 do (AreaKey = "TO")
|
|
if GameArea.selection == 6 do (AreaKey = "PL")
|
|
if GameArea.selection == 7 do (AreaKey = "PV")
|
|
if GameArea.selection == 8 do (AreaKey = "SH")
|
|
if GameArea.selection == 9 do (AreaKey = "LA")
|
|
if GameArea.selection == 10 do (AreaKey = "AS")
|
|
if GameArea.selection == 11 do (AreaKey = "SU")
|
|
-- DL is the detail level
|
|
DL = (DRLevel.value as integer) as string
|
|
if renderSeperate.checked and i == 2 do
|
|
DL = (BranchDRLevel.value as integer) as string
|
|
-- initialize some arrays
|
|
BitMapArray = #()
|
|
OpacityMapArray = #()
|
|
DRObjectsArray = #()
|
|
-- Set the Background color to black
|
|
backgroundColor = (color 0 0 0)
|
|
-- grab and set the Ambient light color to what's specified in the interface
|
|
AmbientColor = AmbientCol.color
|
|
-- setup field of vision
|
|
fov = 10
|
|
CObjSize = (CObj.max - CObj.min)
|
|
|
|
-- if center to base is checked, we determine the center of the lowest set of
|
|
-- vertices in the mesh (the bottom of the trunk) and set the x,y center position to that.
|
|
-- This way, we can make sure that the base of the trunk in each image view lies at the same position.
|
|
-- Otherwise, we just use the object center
|
|
ObjCenter = CObj.center
|
|
|
|
theta = fov
|
|
offsetHeight = false
|
|
-- here, we find the largest distance of either the height,
|
|
-- or the distance between the x,y coordinates of the .min and .max (thus the maximun diameter)
|
|
if (distance [CObj.max.x,CObj.max.y] [CObj.min.x,CObj.min.y]) > (CObj.max.z - CObj.min.z) then
|
|
(
|
|
d = (distance [CObj.max.x,CObj.max.y] [CObj.min.x,CObj.min.y])
|
|
offsetHeight = true
|
|
if debug do format "Using objects maximum DIAMETER for largest dimension...\n"
|
|
) else (
|
|
d = (CObj.max.z - CObj.min.z)
|
|
if debug do format "Using objects maximum HEIGHT for largest dimension...\n"
|
|
)
|
|
|
|
status1.text = "Calculating Camera..."
|
|
-- setup the camera and it's position so that the object lies square in it's viewport
|
|
h = (d / (2 * sin(theta / 2)))
|
|
x = h * (cos(theta))
|
|
NewCamera = targetCamera()
|
|
NewCamera.fov = fov
|
|
NewCamera.target = targetObject()
|
|
NewCamera.target.pos = ObjCenter
|
|
-- Set the camera direction as the light direction
|
|
NewDir = SunArray[GameArea.selection]
|
|
-- NewDir = normalize [NewDir.x, NewDir.y,0]
|
|
|
|
NewCamera.pos = NewCamera.target.pos + NewDir * x
|
|
CameraDist = (distance NewCamera.pos Newcamera.target.pos)
|
|
|
|
BoxDimension = ((CameraDist * (tan(fov * 0.5))) * 2)
|
|
BitMapSizeValue = BitMapSize.value as integer
|
|
|
|
-- generate the texturemap - this will (should) never be seen so we'll make it bright red.
|
|
TMap = CreateBitmap BitMapSizeValue BitMapSizeValue (color 20 77 12)
|
|
|
|
-- prep the materials for opacity map rendering
|
|
if classof CObj.mat == StandardMaterial do
|
|
(
|
|
CObj.mat.diffuse = (color 255 255 255)
|
|
CObj.mat.DiffuseMapEnable = false
|
|
CObj.mat.BumpMapEnable = false
|
|
CObj.mat.shinestrength = 0.0
|
|
CObj.mat.selfIllum = 100
|
|
)
|
|
|
|
if classof CObj.mat == multiMaterial do
|
|
(
|
|
ns = CObj.mat.numsubs
|
|
for j = 1 to ns do
|
|
(
|
|
CObj.mat[j].diffuse = (color 255 255 255)
|
|
CObj.mat[j].DiffuseMapEnable = false
|
|
CObj.mat[j].BumpMapEnable = false
|
|
CObj.mat[j].shinestrength = 0.0
|
|
CObj.mat[j].selfIllum = 100
|
|
)
|
|
)
|
|
|
|
-- render the opacity map
|
|
OpacityMap = (render camera:NewCamera outputwidth:BitMapSizeValue outputheight:BitMapSizeValue vfb:off)
|
|
|
|
CObj.mat = OriginalMat
|
|
|
|
if classof CObj.mat == StandardMaterial do
|
|
(
|
|
CObj.mat.DiffuseMapEnable = true
|
|
CObj.mat.BumpMapEnable = true
|
|
CObj.mat.shinestrength = 0.0
|
|
CObj.mat.selfIllum = 0.0
|
|
)
|
|
|
|
if classof CObj.mat == multiMaterial do
|
|
(
|
|
ns = CObj.mat.numsubs
|
|
for j = 1 to ns do
|
|
(
|
|
CObj.mat[j].DiffuseMapEnable = true
|
|
CObj.mat[j].BumpMapEnable = true
|
|
CObj.mat[j].shinestrength = 0.0
|
|
CObj.mat[j].selfIllum = 0.0
|
|
)
|
|
)
|
|
|
|
CNamePrefix = ""
|
|
CNameSuffix = ""
|
|
|
|
DetailReductionLevel = 5
|
|
for j = 1 to CObj.name.count do
|
|
if CObj.name[j] == "~" do
|
|
MagicIndex = j
|
|
if MagicIndex != undefined then
|
|
(
|
|
CNamePrefix = substring CObj.name 1 (MagicIndex - 1)
|
|
CNameSuffix = ((substring CObj.name (MagicIndex + 1) 3) + (DetailReductionLevel as string))
|
|
) else (
|
|
for j = 1 to CObj.name.count do
|
|
if CObj.name[j] == "-" do
|
|
MagicIndex = j
|
|
|
|
if magicIndex == undefined do
|
|
MagicIndex = CObj.name.count
|
|
|
|
CNamePrefix = substring CObj.name 1 (MagicIndex - 1)
|
|
CNameSuffix = ((substring CObj.name (MagicIndex + 1) 3) + (DetailReductionLevel as string))
|
|
)
|
|
|
|
-- ************************************************************
|
|
-- ** Process the bitmaps *************************************
|
|
-- ************************************************************
|
|
-- process the bitmaps for size/scale
|
|
if debug do format "Processing Bitmaps...\n"
|
|
BitmapInfo = ThresholdBitmap OpacityMap (OpacityThresh.value as integer)
|
|
if debug do
|
|
(
|
|
format "%\n" BitmapInfo
|
|
display OpacityMap
|
|
)
|
|
-- calculate the width and height scalar values for the geometry based on the new cropped areas
|
|
WidthScalar = BitmapInfo[3].x as float / OpacityMap.width
|
|
HeightScalar = BitmapInfo[3].y as float / OpacityMap.height
|
|
|
|
-- crop the bitmaps
|
|
-- OpacityMap = CropBitmap BitmapInfo[1] BitmapInfo[2] BitmapInfo[3]
|
|
-- TMap = CropBitmap TMap BitmapInfo[2] BitmapInfo[3]
|
|
|
|
OpacityMap = CropBitmap BitmapInfo[1] BitmapInfo[2] [(BitmapInfo[3].x), BitmapInfo[3].y]
|
|
TMap = CropBitmap TMap BitmapInfo[2] [(BitmapInfo[3].x), BitmapInfo[3].y]
|
|
|
|
NewBitMapHeight = BitmapInfo[3].y
|
|
NewBitMapWidth = BitmapInfo[3].x
|
|
|
|
-- Extra checking for illegal map sizes (> 256, < 8)
|
|
if NewBitMapHeight > 256 do NewBitMapHeight = 256
|
|
if NewBitMapWidth > 256 do NewBitMapWidth = 256
|
|
if NewBitMapHeight < 8 do NewBitMapHeight = 8
|
|
if NewBitMapWidth < 8 do NewBitMapWidth = 8
|
|
|
|
if RescaleBitmaps.checked do
|
|
(
|
|
reCalc = true
|
|
if (i == 2 and BranchOverRideBitmapSize.checked) do
|
|
(
|
|
NewBitMapWidth = BranchWidthOveride.value
|
|
NewBitMapHeight = BranchHeightOveride.value
|
|
reCalc = false
|
|
)
|
|
|
|
if (OverRideBitmapSize.checked and (i == 1) and (CObj == CTrunk)) do
|
|
(
|
|
NewBitMapWidth = TrunkWidthOveride.value
|
|
NewBitMapHeight = TrunkHeightOveride.value
|
|
reCalc = false
|
|
)
|
|
|
|
if reCalc == true do
|
|
(
|
|
-- calculate the new bitmap dimensions to the nearest power of two size
|
|
NewBitMapWidth = NearPowOfTwo NewBitMapWidth sizeMaps.state
|
|
NewBitMapHeight = NearPowOfTwo NewBitMapHeight sizeMaps.state
|
|
NSize = (PowOfLimit NewBitMapWidth NewBitMapHeight)
|
|
NewBitMapWidth = NSize.x as integer
|
|
NewBitMapHeight = NSize.y as integer
|
|
)
|
|
)
|
|
|
|
if debug do format "Initial BitmapSize: %\t%\nNew Bitmap size: %\t%\n" BitmapInfo[3].x BitmapInfo[3].y NewBitMapWidth NewBitMapHeight
|
|
|
|
FinalOpName = (WorkingFolder + CNamePrefix + "5~" + CNameSuffix + "o8.bmp")
|
|
FinalTexName = (WorkingFolder + CNamePrefix + "5~" + CNameSuffix + "t2.bmp")
|
|
InTexName = (WorkingFolder + "t5.bmp")
|
|
OutTexName = (WorkingFolder + "t_5.bmp")
|
|
InOpName = (WorkingFolder + "o5.bmp")
|
|
OutOpName = (WorkingFolder + "o_5.bmp")
|
|
|
|
-- set the filenames...
|
|
NewOp = bitmap NewBitMapWidth NewBitMapHeight
|
|
NewTex = bitmap NewBitMapWidth NewBitMapHeight
|
|
|
|
if debug do format "Bitmap Size: % %\n" NewBitMapWidth NewBitMapHeight
|
|
|
|
try (
|
|
copy OpacityMap NewOp
|
|
copy TMap NewTex
|
|
) catch (
|
|
MessageBox "Something fucked up.\nGo get Kyle."
|
|
)
|
|
|
|
-- Start the Graham's Scan
|
|
-- Identify all the edge pixels
|
|
status1.text = "Identifying Edges...."
|
|
p = IdentifyEdges NewOp YIncrement.value
|
|
|
|
-- add some random jitter to the array of points so the angle array will sort properly
|
|
aj = AngleJitter.value
|
|
for j = 1 to p.count do
|
|
(
|
|
if p[j].x == 0 do (p[j].x += (random 0 aj))
|
|
if p[j].y == 0 do (p[j].y += (random 0 aj))
|
|
if p[j].x == NewOp.width do (p[j].x += (random -aj 0))
|
|
if p[j].y == NewOp.height do (p[j].y += (random -aj 0))
|
|
if p[j].x < NewOp.width and p[j].x > 0 do (p[j].x += (random -aj aj))
|
|
if p[j].y < NewOp.height and p[j].y > 0 do (p[j].y += (random -aj aj))
|
|
)
|
|
|
|
-- do the Graham Scan
|
|
status1.text = "Calculating convex hull..."
|
|
Hullpoints = GrahamScan p
|
|
-- remove the jitter to the array of points are integers again
|
|
for j = 1 to Hullpoints.count do
|
|
(Hullpoints[j] = [(rnd Hullpoints[j].x), (rnd Hullpoints[j].y)])
|
|
status1.text = "Reducing Points..."
|
|
HullPoints = pruneClosePoints HullPoints PrunePointsThreshold.value
|
|
|
|
NewOp.filename = InOpName
|
|
NewTex.filename = InTexName
|
|
|
|
-- Delete the files (if they're already there)
|
|
DeleteFile NewOp.filename
|
|
DeleteFile NewTex.filename
|
|
|
|
-- and save them...
|
|
save NewTex
|
|
save NewOp
|
|
|
|
-- if debug do format "Starting Alchemy...\n"
|
|
-- Process Maps via Alchemy
|
|
doscommand ("alchemy -w -o -b " + InOpName + " " + OutOpName)
|
|
doscommand ("alchemy -w -o " + InTexName + " " + OutTexName)
|
|
|
|
if debug do format "Alchemy Done!...\nProcessing Bitmaps Finished!\n"
|
|
|
|
-- Delete files that may already be there
|
|
deleteFile FinalOpName
|
|
deleteFile FinalTexName
|
|
|
|
-- Copy the processed bitmaps to their final name/location
|
|
copyFile OutOpName FinalOpName
|
|
copyFile OutTexName FinalTexName
|
|
-- ************************************************************
|
|
-- ** Create the new mesh *************************************
|
|
-- ************************************************************
|
|
if debug do format "Building Geometry...\n"
|
|
|
|
-- calculate the new uv's for Hullpoints
|
|
status1.text = "Calculating Texture Vertices..."
|
|
minX = HullPoints[1].x
|
|
maxX = HullPoints[1].x
|
|
minY = HullPoints[1].y
|
|
maxY = HullPoints[1].y
|
|
for i = 1 to HullPoints.count do
|
|
(
|
|
if HullPoints[i].x > maxX do maxX = HullPoints[i].x
|
|
if HullPoints[i].x < minX do minX = HullPoints[i].x
|
|
if HullPoints[i].y > maxY do maxY = HullPoints[i].y
|
|
if HullPoints[i].y < minY do minY = HullPoints[i].y
|
|
)
|
|
|
|
iWidth = maxX - minX
|
|
iHeight = maxY - minY
|
|
iDimension = [iWidth, iHeight]
|
|
iCorner = [minX, minY]
|
|
|
|
du = 1.0 / iWidth
|
|
dv = 1.0 / iHeight
|
|
|
|
-- flip all the y points
|
|
for j = 1 to Hullpoints.count do (Hullpoints[j].y = iHeight - Hullpoints[j].y)
|
|
|
|
TVertArray = #()
|
|
for j = 1 to Hullpoints.count do
|
|
(
|
|
Tvert = [(HullPoints[j].x * du), (HullPoints[j].y * dv),1.0]
|
|
append TVertArray Tvert
|
|
)
|
|
|
|
|
|
BoxDimension = ((distance NewCamera.pos NewCamera.target.pos) * (tan(fov * 0.5))) * 2
|
|
PixelSize = (BoxDimension as float / BitMapSizeValue as float)
|
|
if debug do format "PixelSize:%\n" PixelSize
|
|
|
|
-- calculate the width and height offsets for the new geometry
|
|
w1 = BitmapInfo[2].x
|
|
w2 = BitmapInfo[1].width - (w1 + BitmapInfo[3].x)
|
|
AvgFreeWidth = (BitmapInfo[1].width - BitmapInfo[3].x) * 0.5
|
|
if w2 >= w1 then
|
|
ObjectOffsetW = (AvgFreeWidth - w1) * PixelSize
|
|
else
|
|
ObjectOffsetW = -(AvgFreeWidth - w2) * PixelSize
|
|
|
|
h1 = BitmapInfo[2].y
|
|
h2 = BitmapInfo[1].height - (h1 + BitmapInfo[3].y)
|
|
AvgFreeHeight = (BitmapInfo[1].height - BitmapInfo[3].y) * 0.5
|
|
if h2 >= h1 then
|
|
ObjectOffsetV = (AvgFreeHeight - h1) * PixelSize
|
|
else
|
|
ObjectOffsetV = -(AvgFreeHeight - h2) * PixelSize
|
|
|
|
if debug do
|
|
(
|
|
format "w1:% w2:% h1:% h2:%\n" w1 w2 h1 h2
|
|
format "Height Offset:%\nWidth Offset:%\nAvg Free: % %\n" ObjectOffsetV ObjectOffsetW AvgFreeWidth AvgFreeHeight
|
|
)
|
|
|
|
NewHeight = BoxDimension as float * HeightScalar
|
|
NewWidth = BoxDimension as float * WidthScalar
|
|
b = box()
|
|
b.width = NewWidth
|
|
b.height = BoxDimension
|
|
b.length = NewHeight
|
|
b.pos = NewCamera.target.pos
|
|
b.dir = -NewCamera.dir
|
|
if debug do
|
|
format "Camera Dir vector @ %: %\n" t -NewCamera.dir
|
|
b.mapcoords = true
|
|
convertToMesh b
|
|
for j = 1 to 4 do deleteVert b b.numverts
|
|
if NewCamera.dir.x < 0.0 do
|
|
in coordsys local rotate b 180 z_axis
|
|
in coordsys local rotate b 180 z_axis
|
|
in coordsys local move b [ObjectOffsetW, ObjectOffsetV, 0]
|
|
-- flip the UV's along U
|
|
if (getTvert b 4).x == 0.0 do
|
|
for j = 1 to b.numtverts do
|
|
(
|
|
CTvert = (getTvert b j)
|
|
if CTvert.x == 1.0 then
|
|
CTvert.x = 0.0
|
|
else
|
|
if CTvert.x == 0.0 do (CTvert.x = 1.0)
|
|
setTvert b j CTvert
|
|
)
|
|
update b
|
|
-- Calculate the new points in 3space via the uv coordinates
|
|
P0 = getVert b 2
|
|
P1 = getVert b 1
|
|
P2 = getVert b 4
|
|
P3 = getVert b 3
|
|
|
|
fVertArray = #()
|
|
|
|
for j = 1 to TVertArray.count do
|
|
(
|
|
Px = (P0.x + (TVertArray[j].x * (P1.x - P0.x)) + (TVertArray[j].y * (P2.x - P0.x)))
|
|
Py = (P0.y + (TVertArray[j].x * (P1.y - P0.y)) + (TVertArray[j].y * (P2.y - P0.y)))
|
|
Pz = (P0.z + (TVertArray[j].x * (P1.z - P0.z)) + (TVertArray[j].y * (P2.z - P0.z)))
|
|
append fVertArray [Px,Py,Pz]
|
|
)
|
|
iFaceArray = #([1,2,3])
|
|
for i = 3 to (Hullpoints.count - 1) do (append iFaceArray [1,i,i+1])
|
|
-- construct the mesh
|
|
delete b
|
|
b = mesh vertices:fVertArray faces:iFaceArray
|
|
if b.numverts > 16 do (format "Warning: more than 16 verts detected in convex hull object... please check and regenerate if needed...\n")
|
|
-- apply the texture coordinates
|
|
addmodifier b (UVWMap())
|
|
convertToMesh b
|
|
for i = 1 to b.numfaces do
|
|
(
|
|
iFace = getFace b i
|
|
iTFace = getTVFace b i
|
|
setTvert b iTFace.x (TVertArray[iFace.x])
|
|
setTvert b iTFace.y (TVertArray[iFace.y])
|
|
setTvert b iTFace.z (TVertArray[iFace.z])
|
|
)
|
|
-- Set the Edge visibility
|
|
for i = 1 to b.numfaces do
|
|
(
|
|
if i == 1 do setEdgeVis b i 3 off
|
|
if i == b.numfaces do setEdgeVis b i 1 off
|
|
if i > 1 and i < b.numfaces do
|
|
(
|
|
SetEdgeVis b i 1 off
|
|
SetEdgeVis b i 3 off
|
|
)
|
|
)
|
|
update b
|
|
|
|
df = #()
|
|
for i = 1 to b.numfaces do
|
|
(
|
|
Cface = getface b i
|
|
n = 4
|
|
NewX = rndP3 (getvert b Cface.x) n
|
|
NewY = rndP3 (getvert b Cface.y) n
|
|
NewZ = rndP3 (getvert b Cface.z) n
|
|
if (Thresh NewX NewY 0.001) do
|
|
if findItem df i == 0 do (append df i)
|
|
|
|
if (Thresh NewX NewZ 0.001) do
|
|
if findItem df i == 0 do (append df i)
|
|
|
|
if (Thresh NewZ NewY 0.001) do
|
|
if findItem df i == 0 do (append df i)
|
|
|
|
-- check for a degenerate normal
|
|
if (GetFaceNormal b i) == [0,0,0] do
|
|
if findItem df i == 0 do (append df i)
|
|
)
|
|
|
|
if df.count > 0 do
|
|
(
|
|
format "found degenerate polygons... deleting them\n"
|
|
for i = df.count to 1 by -1 do
|
|
deleteFace b df[i]
|
|
update b
|
|
)
|
|
|
|
-- Check for Stray Vertices
|
|
StrayVertArray = (for i = 1 to b.numverts collect i)
|
|
UsedVerts = #()
|
|
NewVertSelection = #()
|
|
|
|
for i = 1 to b.numfaces do
|
|
(
|
|
CFace = (getface b i)
|
|
if (findItem UsedVerts CFace.x) == 0 do (append UsedVerts CFace.x)
|
|
if (findItem UsedVerts CFace.y) == 0 do (append UsedVerts CFace.y)
|
|
if (findItem UsedVerts CFace.z) == 0 do (append UsedVerts CFace.z)
|
|
)
|
|
|
|
for i = 1 to StrayVertArray.count do
|
|
if (findItem UsedVerts i) == 0 do (append NewVertSelection i)
|
|
|
|
if NewVertSelection.count > 0 then
|
|
(
|
|
format "Stray vertices were found... deleting them\n"
|
|
for i = NewVertSelection.count to 1 by -1 do
|
|
deleteVert b NewVertSelection[i]
|
|
update b
|
|
)
|
|
|
|
if debug do format "Geometry done!\n"
|
|
|
|
-- ************************************************************
|
|
-- ** Generate a new material
|
|
-- ************************************************************
|
|
-- make sure all face IDs are set to 1
|
|
if debug do
|
|
format "Building new material...\n"
|
|
for j = 1 to b.numfaces do setFaceMatID b j 1
|
|
NMat = standardMaterial()
|
|
-- give it a random color
|
|
NMat.diffuse = random (color 20 20 20) (color 220 220 220)
|
|
NMat.diffuseMap = bitmaptexture()
|
|
NMat.OpacityMap = bitmaptexture()
|
|
-- specify the bitmap names
|
|
NMat.diffuseMap.filename = FinalTexName
|
|
NMat.OpacityMap.filename = FinalOpName
|
|
NMat.shinestrength = 0.0
|
|
NMat.name = substring OutTexName 1 (OutTexName.count - 3)
|
|
NMat.selfIllum = 100
|
|
b.mat = NMat
|
|
if debug do format "Finished building new material!\n"
|
|
|
|
b.wirecolor = scaleColor cw 0.3
|
|
b.name = ("$" + (substring CObj.name 1 (CObj.name.count - 4)) + "5-00")
|
|
b.pivot = CObj.pivot
|
|
if debug != true do
|
|
(
|
|
delete NewCamera
|
|
NewCamera = undefined
|
|
)
|
|
CObj.mat = OriginalMat
|
|
)
|
|
) else (
|
|
if renderSeperate.checked do MessageBox "No Objects Defined!"
|
|
)
|
|
gc() -- collect some garbage
|
|
)
|
|
)
|
|
-- Lonnie, comment the next line out "--"
|
|
-- if SingleObject == true do delete CTrunk
|
|
delete CTrunk
|
|
if CBranches != undefined do delete CBranches
|
|
-- unhide everything at the end...
|
|
for o in objects do unhide o
|
|
CTrunk = CBranches = undefined
|
|
) else (
|
|
MessageBox "You must initialize the objects first"
|
|
)
|
|
)
|
|
)
|
|
|
|
on DRRollout open do
|
|
(
|
|
MagicIndex = undefined
|
|
offsetHeight = false
|
|
HeightOffset = 0.0
|
|
)
|
|
)
|
|
|
|
-- ******************************************************************************************************************************
|
|
-- * Utility Open
|
|
-- ******************************************************************************************************************************
|
|
on DetailReduction open do
|
|
(
|
|
if flip == undefined do
|
|
global flip = false
|
|
if (getfiles "C:\DR.txt").count == 0 then
|
|
(
|
|
if (WorkingFolder = (GetSavePath caption:"Select the location of a temporary folder to use for keeping texturemaps")) != undefined do
|
|
(
|
|
f = createfile "C:\DR.txt"
|
|
openfile "DR.txt"
|
|
WorkingFolder = (WorkingFolder + "\\")
|
|
format ("Working Location: " + WorkingFolder) to:f
|
|
close f
|
|
format "Working Folder initialized to: %\n" WorkingFolder
|
|
)
|
|
) else (
|
|
f = openfile "C:\DR.txt"
|
|
CLine = readline f
|
|
for i = 1 to CLine.count do
|
|
(
|
|
if cLine[i] == ":" do
|
|
(
|
|
WorkingFolder = (substring CLine (i + 2) (CLine.count - i - 1))
|
|
if substring WorkingFolder WorkingFolder.count 1 != "\\" do
|
|
WorkingFolder = WorkingFolder + "\\"
|
|
format "Working Location initialized to: %\n" WorkingFolder
|
|
Exit
|
|
)
|
|
)
|
|
close f
|
|
)
|
|
|
|
Flt = NewRolloutFloater "Detail Reduction v 1.5.2" 400 745 800 200
|
|
addrollout DRRollout Flt
|
|
gc()
|
|
)
|
|
|
|
on DetailReduction close do
|
|
closeRolloutFloater Flt
|
|
|
|
label DRLabel1 "Detail Reduction"
|
|
label DRLabel2 "v 1.5.2, 7.14.98"
|
|
) |