Match plane to curve
This snippet matches a plane (hPlane) to a curve (nCurveId) of a shape (hCuveObj) with a distance to the curve of nWidth/2. It simply takes the vertices of the plane (even number of vertices required) and positions them along the curve (in the x/y plane).
Make sure your plane has enough vertices to enable big changes in the curvature, otherwise you will have overlaps and z-fighting.
--------------------------------------------------------------------------------
function YourAI.matchPlaneToCurve ( hPlane, hCurveObj, nCurveId, nWidth )
--------------------------------------------------------------------------------
local hMesh = shape.getMesh ( hPlane )
local nSubSetIndex = 0;
local nSubSetVertices = mesh.getSubsetVertexCount ( hMesh, nSubSetIndex )
if(math.mod (nSubSetVertices, 2) ~= 0)
then
log.message ("ERROR: uneven number of vertices in hPlane!")
return
end
local cX, cY, cZ
local cX1, cY1, cZ1
local cX2, cY2, cZ2
local tX, tY, tZ
local tnX, tnY, tnZ
local pX, pY, pZ
local numVerticesHalf = nSubSetVertices * 0.5 - 1
local cEvalStep = 1.0 / numVerticesHalf
local cEvalPos = 0.0
if ( mesh.lockSubsetVertexBuffer ( hMesh, nSubSetIndex, mesh.kLockReadWrite ) )
then
for i = 0, nSubSetVertices - 1
do
if(math.mod (i, 2) == 0)
then
-- left side of curve
cX, cY, cZ = shape.evaluateCurve ( hCurveObj, nCurveId, cEvalPos )
cX1, cY1, cZ1 = shape.evaluateCurve ( hCurveObj, nCurveId, cEvalPos + 0.01 )
cX2, cY2, cZ2 = shape.evaluateCurve ( hCurveObj, nCurveId, cEvalPos - 0.01 )
tX, tY, tZ = math.vectorSubtract ( cX1, cY1, cZ1, cX2, cY2, cZ2 )
tnX, tnY, tnZ = math.vectorNormalize ( tX, tY, tZ )
tnX, tnY, tnZ = math.vectorScale ( tnX, tnY, tnZ, nWidth * 0.5 )
-- convert from curve space into plane space
pX, pY, pZ = this.convertPointFromTo ( hCurveObj, hPlane, cX - tnY, cY + tnX, cZ )
-- update vertex
mesh.setSubsetVertexPosition ( hMesh, nSubSetIndex, i, pX, pY, pZ )
else
-- right side of curve
cX, cY, cZ = shape.evaluateCurve ( hCurveObj, nCurveId, cEvalPos )
cX1, cY1, cZ1 = shape.evaluateCurve ( hCurveObj, nCurveId, cEvalPos + 0.01 )
cX2, cY2, cZ2 = shape.evaluateCurve ( hCurveObj, nCurveId, cEvalPos - 0.01 )
tX, tY, tZ = math.vectorSubtract ( cX1, cY1, cZ1, cX2, cY2, cZ2 )
tnX, tnY, tnZ = math.vectorNormalize ( tX, tY, tZ )
tnX, tnY, tnZ = math.vectorScale ( tnX, tnY, tnZ, nWidth * 0.5 )
-- convert from curve space into plane space
pX, pY, pZ = this.convertPointFromTo ( hCurveObj, hPlane, cX + tnY, cY - tnX, cZ )
-- update eval position
cEvalPos = cEvalPos + cEvalStep;
-- update vertex
mesh.setSubsetVertexPosition ( hMesh, nSubSetIndex, i, pX, pY, pZ )
end
end
-- unlock mesh
mesh.unlockSubsetVertexBuffer ( hMesh, nSubSetIndex )
mesh.updateBoundingVolumes ( hMesh )
end
--------------------------------------------------------------------------------
end
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
function YourAI.convertPointFromTo ( hObjFrom, hObjTo, nX, nY, nZ)
--------------------------------------------------------------------------------
if(hObjFrom == nil or hObjTo == nil) then return end
local gX, gY, gZ = object.transformPoint ( hObjFrom, nX, nY, nZ, object.kLocalSpace, object.kGlobalSpace )
local lX, lY, lZ = object.transformPoint ( hObjTo, gX, gY, gZ, object.kGlobalSpace, object.kLocalSpace )
return lX, lY, lZ
--------------------------------------------------------------------------------
end
--------------------------------------------------------------------------------