|
|
PatchWork(PointArray) takes a two dimension array of point vectors as a map
from which it constructs a bicubic mesh. It is smaller and faster than its
predecessor, bigPatch. It is also much more capable: the points don't need
to be on a rectangular grid, so long as they proceed from smallest value to
largest value in the x and z dimensions. PatchWork also seems to handle
uv_mapping properly (which was a big problem with the earlier version).
This is still an alpha pre-release (v0.83 if anyone is counting). I'm not
aware of any bugs at this point.
Here's the code:
===============================================
#macro PatchWork (G) object {
#local Cols = dimension_size(G, 2); // number of cols
#local Rows = dimension_size(G, 1); // number of rows
union {
#local R = 0;
#while (R<Rows-1)
#local C=0;
#while (C<Cols-1)
#local BLC = G[R][C]; // bot left corner current
patch
#local BRC = G[R][C+1]; // bot right corner
#local TLC = G[R+1][C]; // top left corner
#local TRC = G[R+1][C+1]; // top right corner
// more horizontal points of interest
#if (C>0)
#local LBLC = G[R][C-1]; // left of bot left corner
#local LTLC = G[R+1][C-1]; // left of top left corner
#else
#local LBLC = BLC;
#local LTLC = TLC;
#end
#if (C+2<Cols)
#local RBRC = G[R][C+2]; // right of bot right corner
#local RTRC = G[R+1][C+2]; // right of top right corner
#else
#local RBRC = BRC;
#local RTRC = TRC;
#end
// more vertical points of interest
#if (R>0)
#local BBLC = G[R-1][C]; // below bottom left corner
#local BBRC = G[R-1][C+1]; // below bottom right corner
#else
#local BBLC = BLC;
#local BBRC = BRC;
#end
#if (R+2<Rows)
#local TTLC = G[R+2][C]; // top of top left corner
#local TTRC = G[R+2][C+1]; // top of top right corner
#else
#local TTLC = TLC;
#local TTRC = TRC;
#end
// There are four diagonal points of interest, too:
#if (C>0)
#if (R>0)
#local LLD = G[R-1][C-1]; // left lower diagonal
#else
#local LLD = BLC;
#end
#if (R+2<Rows)
#local LUD = G[R+2][C-1]; // left upper diagonal
#else
#local LUD = TLC;
#end
#else
#local LLD = BLC;
#local LUD = TLC;
#end
#if (C+2<Cols)
#if (R>0)
#local RLD = G[R-1][C+2]; // right lower diagonal
#else
#local RLD = BRC;
#end
#if (R+2<Rows)
#local RUD = G[R+2][C+2]; // right upper diagonal
#else
#local RUD = TRC;
#end
#else
#local RLD = BRC;
#local RUD = TRC;
#end
// following for uv_vectors
#local iX = G[0][0].x;
#local iZ = G[0][0].z;
#local denX = G[Rows-1][Cols-1].x-iX;
#local denZ = G[Rows-1][Cols-1].z-iZ;
bicubic_patch { type 1 flatness 0 u_steps 3 v_steps 3
uv_vectors <(BLC.x-iX)/denX, (BLC.z-iZ)/denZ>,
<(BRC.x-iX)/denX, (BRC.z-iZ)/denZ>,
<(TRC.x-iX)/denX, (TRC.z-iZ)/denZ>,
<(TLC.x-iX)/denX, (TLC.z-iZ)/denZ>
// row 0
BLC // a given point
(
((LBLC.y<BLC.y&BLC.y<BRC.y)|(LBLC.y>BLC.y&BLC.y>BRC.y))?(BLC+BRC)/2:
<(BLC.x+BRC.x)/2, BLC.y, (BLC.z+BRC.z)/2> )
(
((BLC.y<BRC.y&BRC.y<RBRC.y)|(BLC.y>BRC.y&BRC.y>RBRC.y))?(BLC+BRC)/2:
<(BLC.x+BRC.x)/2, BRC.y, (BLC.z+BRC.z)/2> )
BRC // a given point
// row 1
(
((BBLC.y<BLC.y&BLC.y<TLC.y)|(BBLC.y>BLC.y&BLC.y>TLC.y))?(BLC+TLC)/2:
<(BLC.x+TLC.x)/2, BLC.y, (BLC.z+TLC.z)/2> )
(
((LLD.y<BLC.y&BLC.y<TRC.y)|(LLD.y>BLC.y&BLC.y>TRC.y))?(BLC+TRC)/2:
<(BLC.x+TRC.x)/2, BLC.y, (BLC.z+TLC.z)/2> )
(
((RLD.y<BRC.y&BRC.y<TLC.y)|(RLD.y>BRC.y&BRC.y>TLC.y))?(BRC+TLC)/2:
<(BRC.x+TLC.x)/2, BRC.y, (BRC.z+TLC.z)/2> )
(
((BBRC.y<BRC.y&BRC.y<TRC.y)|(BBRC.y>BRC.y&BRC.y>TRC.y))?(BRC+TRC)/2:
<(BRC.x+TRC.x)/2, BRC.y, (BRC.z+TRC.z)/2> )
// row 2
(
((BLC.y<TLC.y&TLC.y<TTLC.y)|(BLC.y>TLC.y&TLC.y>TTLC.y))?(TLC+BLC)/2:
<(TLC.x+BLC.x)/2, TLC.y, (TLC.z+BLC.z)/2> )
(
((BRC.y<TLC.y&TLC.y<LUD.y)|(BRC.y>TLC.y&TLC.y>LUD.y))?(BRC+TLC)/2:
<(BRC.x+TLC.x)/2, TLC.y, (BRC.z+TLC.z)/2> )
(
((BLC.y<TRC.y&TRC.y<RUD.y)|(BLC.y>TRC.y&TRC.y>RUD.y))?(BLC+TRC)/2:
<(BLC.x+TRC.x)/2, TRC.y, (BLC.z+TLC.z)/2> )
(
((BRC.y<TRC.y&TRC.y<TTRC.y)|(BRC.y>TRC.y&TRC.y>TTRC.y))?(TRC+BRC)/2:
<(TRC.x+BRC.x)/2, TRC.y, (TRC.z+BRC.z)/2> )
// row 3
TLC
(
((LTLC.y<TLC.y&TLC.y<TRC.y)|(LTLC.y>TLC.y&TLC.y>TRC.y))?(TLC+TRC)/2:
<(TLC.x+TRC.x)/2, TLC.y, (TLC.z+TRC.z)/2> )
(
((TLC.y<TRC.y&TRC.y<RTRC.y)|(TLC.y>TRC.y&TRC.y>RTRC.y))?(TLC+TRC)/2:
<(TLC.x+TRC.x)/2, TRC.y, (TLC.z+TRC.z)/2> )
TRC
}
#local C=C+1;
#end
#local R=R+1;
#end
}
}
#end
#declare pwTest = array[5][5] {
{ < 0, 0, 0>, < 1, 0, 0>, < 2, 0, 0>, < 3, 0, 0>, < 4, 0, 0> },
{ < 0, 0, 1>, < 1.7, 1, 1.7>, < 2, 0, 1>, < 3, 1, 1>, < 4, 0, 1> },
{ < 0, 0, 2>, < 1, 0, 2>, < 2, 0, 2>, < 3, 0, 2>, < 4, 0, 2> },
{ < 0, 0, 3>, < 1,-1, 3>, < 2, 0, 3>, < 3,-1, 3>, < 4, 0, 3> },
{ < 0, 0, 4>, < 1, 0, 4>, < 2, 0, 4>, < 3, 0, 4>, < 4, 0, 4> }
}
#include "colors.inc"
#include "textures.inc"
light_source { <5,25,-10> rgb <1,1,0.8> }
camera { location < 1.1, 3, -1.1> look_at <2,0,2> angle 67 }
object { PatchWork( pwTest )
uv_mapping
texture {
pigment {
image_map {
png "PiThing.png"
map_type 0 // planar, from <0,0,0> to <1,1,0>
interpolate 0
once
}
}
// finish { Shiny }
}
}
// eof
=========================================
--
Will Woodhull
Thornhenge, SW Oregon, USA
willl.at.thornhenge.net
Post a reply to this message
|
|