738 lines
25 KiB
Scheme
Executable File
738 lines
25 KiB
Scheme
Executable File
|
|
//////////////////////////////////////////////////////////////////////
|
|
/* z_volumes.sch */
|
|
/* Author: DJ Jones */
|
|
/* By including this file and calling UPDATE_ZVOLUME_WIDGETS each */
|
|
/* frame, you will find a set of widgets called Script/Z-Aligned */
|
|
/* Volumes. Here, you can draw a variety of volumetric shapes and */
|
|
/* grab the data for use with ANGLED_AREA checks or other collision */
|
|
/* functionality. */
|
|
//////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
// This file contains debug-only functionality.
|
|
#IF IS_DEBUG_BUILD
|
|
|
|
|
|
USING "commands_debug.sch"
|
|
USING "commands_camera.sch"
|
|
USING "commands_object.sch"
|
|
USING "script_maths.sch"
|
|
USING "script_player.sch"
|
|
|
|
|
|
CONST_INT iMAX_ZVC_VERTS 80
|
|
|
|
|
|
// A volume that rotates freely on the z axis.
|
|
// Can be interpreted as a rectangular prism, elliptic cylinder, or elliptoid.
|
|
// Does not support negative dimensions.
|
|
// fWidth = x, fDepth = y, fHeight = z; fRotation is rotation on z-axis in degrees.
|
|
STRUCT zVolume
|
|
VECTOR vCenter
|
|
FLOAT fWidth
|
|
FLOAT fDepth
|
|
FLOAT fHeight
|
|
FLOAT fRotation
|
|
ENDSTRUCT
|
|
|
|
// A triangle with three vertices.
|
|
//STRUCT zTriangle
|
|
// VECTOR p1, p2, p3
|
|
//ENDSTRUCT
|
|
|
|
|
|
// Control variables for widgets.
|
|
FLOAT zvw_fPosX // Center position x
|
|
FLOAT zvw_fPosY // Center position y
|
|
FLOAT zvw_fPosZ // Center position z
|
|
FLOAT zvw_fDimX // Width
|
|
FLOAT zvw_fDimY // Depth
|
|
FLOAT zvw_fDimZ // Height
|
|
FLOAT zvw_fRotZ // Rot on z axis in deg
|
|
BOOL zvw_bPosSnapPlr // Snap volume pos to player
|
|
BOOL zvw_bRotSnapPlr // Snap volume rot to player
|
|
BOOL zvw_bPosSnapCam // Snap volume pos to cam
|
|
BOOL zvw_bRotSnapCam // Snap volume rot to cam
|
|
BOOL zvw_bPosSnapOrg // Snap volume pos to origin
|
|
BOOL zvw_bRotSnapOrg // Snap volume rot to zero
|
|
BOOL zvw_bDefaultDim // Back to default dims
|
|
BOOL zvw_bDrawMaster // Master draw control
|
|
BOOL zvw_bDrawAsRec // Consider as rect prism
|
|
BOOL zvw_bDrawAsCyl // Consider as ellip cyl
|
|
BOOL zvw_bDrawAsEld // Consider as elliptoid
|
|
INT zvw_iSubdiv // Subdivisions (pie pieces)
|
|
BOOL zvw_bDrawWire // Wireframe draw control
|
|
INT zvw_iAlphaWire // Wireframe alpha
|
|
BOOL zvw_bDrawFace // Face draw control
|
|
INT zvw_iAlphaFace // Face alpha
|
|
BOOL zvw_bDoCollision // Perform collision checks
|
|
BOOL zvw_bVolCheckPlr // Player in volume status
|
|
BOOL zvw_bVolCheckCam // Camera in volume status
|
|
VECTOR zvw_vAngMidpt1 // Midpt 1 for angled area
|
|
VECTOR zvw_vAngMidpt2 // Midpt 2 for angled area
|
|
FLOAT zvw_fAngMidpt1x // Angled area midpt 1 x
|
|
FLOAT zvw_fAngMidpt1y // Angled area midpt 1 y
|
|
FLOAT zvw_fAngMidpt1z // Angled area midpt 1 z
|
|
FLOAT zvw_fAngMidpt2x // Angled area midpt 2 x
|
|
FLOAT zvw_fAngMidpt2y // Angled area midpt 2 y
|
|
FLOAT zvw_fAngMidpt2z // Angled area midpt 2 z
|
|
FLOAT zvw_fAngWidth // Width for angled area
|
|
|
|
// Do not touch
|
|
WIDGET_GROUP_ID zvw_zVolumeWidgets
|
|
WIDGET_GROUP_ID zvw_posDimGroup
|
|
WIDGET_GROUP_ID zvw_renderingGroup
|
|
WIDGET_GROUP_ID zvw_collisionGroup
|
|
WIDGET_GROUP_ID zvw_angledAreaGroup
|
|
INT zvw_iMode
|
|
BOOL zvw_bInit
|
|
zVolume zvw_Volume
|
|
//zTriangle zvw_Triangles[512]
|
|
|
|
|
|
// Get the zVolume equivalent of an area check (as in IS_ENTITY_IN_AREA)
|
|
PROC GET_ZVOLUME_FROM_AREA(zVolume &vol, VECTOR vCorner1, VECTOR vCorner2, BOOL bDo3DCheck)
|
|
vol.vCenter = <<0.5 * (vCorner1.x + vCorner2.x), 0.5 * (vCorner1.y + vCorner2.y), 0.5 * (vCorner1.z + vCorner2.z)>>
|
|
vol.fWidth = ABSF(vCorner2.x - vCorner1.x)
|
|
vol.fDepth = ABSF(vCorner2.y - vCorner1.y)
|
|
vol.fHeight = PICK_FLOAT(bDo3DCheck, ABSF(vCorner2.z - vCorner1.z), 10000.0)
|
|
vol.fRotation = 0.0
|
|
ENDPROC
|
|
|
|
// Get the midpoints and width of an angled area based on a z-volume.
|
|
PROC GET_ANGLED_AREA_FROM_ZVOLUME(zVolume vol, VECTOR& vMidpt1, VECTOR& vMidpt2, FLOAT& fWidth)
|
|
VECTOR vProj
|
|
FLOAT fSin = SIN(vol.fRotation)
|
|
FLOAT fCos = COS(vol.fRotation)
|
|
FLOAT fHalfWidth = 0.5 * vol.fWidth
|
|
|
|
vProj.x = fCos * fHalfWidth
|
|
vProj.y = fSin * fHalfWidth
|
|
vMidpt1 = vol.vCenter + vProj
|
|
vMidpt2 = vol.vCenter - vProj
|
|
fWidth = vol.fDepth
|
|
ENDPROC
|
|
|
|
// Get the bottom center point of a zVolume, usually for a cylinder.
|
|
//FUNC VECTOR GET_ZVOLUME_BOTTOM(zVolume vol)
|
|
// vol.vCenter.z -= 0.5 * vol.fHeight
|
|
// RETURN vol.vCenter
|
|
//ENDFUNC
|
|
|
|
// Debug draw for rectangular prism.
|
|
PROC DRAW_ZVOLUME_REC(zVolume vol, BOOL bDrawWire, BOOL bDrawFace)
|
|
VECTOR vUNE, vUNW, vUSW, vUSE, vLNE, vLNW, vLSW, vLSE
|
|
VECTOR vNProj, vSProj, vWProj, vEProj, vUProj, vDProj
|
|
|
|
// Quit if there's nothing to do.
|
|
IF NOT bDrawWire AND NOT bDrawFace
|
|
EXIT
|
|
ENDIF
|
|
|
|
// Create projection vectors.
|
|
vEProj = <<COS(vol.fRotation), SIN(vol.fRotation), 0.0>>
|
|
vNProj = <<-vEProj.y, vEProj.x, 0.0>>
|
|
vEProj *= vol.fWidth * 0.5
|
|
vWProj = -vEProj
|
|
vNProj *= vol.fDepth * 0.5
|
|
vSProj = -vNProj
|
|
vUProj = <<0.0, 0.0, 0.5 * vol.fHeight>>
|
|
vDProj = <<0.0, 0.0, -0.5 * vol.fHeight>>
|
|
|
|
// Create vertices.
|
|
vUNE = vol.vCenter + vUProj + vNProj + vEProj
|
|
vUNW = vol.vCenter + vUProj + vNProj + vWProj
|
|
vUSW = vol.vCenter + vUProj + vSProj + vWProj
|
|
vUSE = vol.vCenter + vUProj + vSProj + vEProj
|
|
vLNE = vol.vCenter + vDProj + vNProj + vEProj
|
|
vLNW = vol.vCenter + vDProj + vNProj + vWProj
|
|
vLSW = vol.vCenter + vDProj + vSProj + vWProj
|
|
vLSE = vol.vCenter + vDProj + vSProj + vEProj
|
|
|
|
// Draw wireframe.
|
|
IF bDrawWire
|
|
DRAW_DEBUG_LINE(vUNE, vUNW, 0, 255, 0, zvw_iAlphaWire)
|
|
DRAW_DEBUG_LINE(vUNW, vUSW, 0, 255, 0, zvw_iAlphaWire)
|
|
DRAW_DEBUG_LINE(vUSW, vUSE, 0, 255, 0, zvw_iAlphaWire)
|
|
DRAW_DEBUG_LINE(vUSE, vUNE, 0, 255, 0, zvw_iAlphaWire)
|
|
DRAW_DEBUG_LINE(vLNE, vLNW, 0, 255, 0, zvw_iAlphaWire)
|
|
DRAW_DEBUG_LINE(vLNW, vLSW, 0, 255, 0, zvw_iAlphaWire)
|
|
DRAW_DEBUG_LINE(vLSW, vLSE, 0, 255, 0, zvw_iAlphaWire)
|
|
DRAW_DEBUG_LINE(vLSE, vLNE, 0, 255, 0, zvw_iAlphaWire)
|
|
DRAW_DEBUG_LINE(vUNE, vLNE, 0, 255, 0, zvw_iAlphaWire)
|
|
DRAW_DEBUG_LINE(vUNW, vLNW, 0, 255, 0, zvw_iAlphaWire)
|
|
DRAW_DEBUG_LINE(vUSW, vLSW, 0, 255, 0, zvw_iAlphaWire)
|
|
DRAW_DEBUG_LINE(vUSE, vLSE, 0, 255, 0, zvw_iAlphaWire)
|
|
ENDIF
|
|
|
|
// Draw faces.
|
|
IF bDrawFace
|
|
DRAW_DEBUG_POLY(vUNE, vUNW, vUSE, 0, 0, 127, zvw_iAlphaFace)
|
|
DRAW_DEBUG_POLY(vUNW, vUSW, vUSE, 0, 0, 127, zvw_iAlphaFace)
|
|
DRAW_DEBUG_POLY(vLNW, vLNE, vLSW, 0, 0, 127, zvw_iAlphaFace)
|
|
DRAW_DEBUG_POLY(vLNE, vLSE, vLSW, 0, 0, 127, zvw_iAlphaFace)
|
|
DRAW_DEBUG_POLY(vLNE, vLNW, vUNE, 0, 0, 127, zvw_iAlphaFace)
|
|
DRAW_DEBUG_POLY(vLNW, vUNW, vUNE, 0, 0, 127, zvw_iAlphaFace)
|
|
DRAW_DEBUG_POLY(vLNW, vLSW, vUNW, 0, 0, 127, zvw_iAlphaFace)
|
|
DRAW_DEBUG_POLY(vLSW, vUSW, vUNW, 0, 0, 127, zvw_iAlphaFace)
|
|
DRAW_DEBUG_POLY(vLSE, vLNE, vUSE, 0, 0, 127, zvw_iAlphaFace)
|
|
DRAW_DEBUG_POLY(vLNE, vUNE, vUSE, 0, 0, 127, zvw_iAlphaFace)
|
|
DRAW_DEBUG_POLY(vLSW, vLSE, vUSW, 0, 0, 127, zvw_iAlphaFace)
|
|
DRAW_DEBUG_POLY(vLSE, vUSE, vUSW, 0, 0, 127, zvw_iAlphaFace)
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
// Debug draw for elliptic cylinder.
|
|
PROC DRAW_ZVOLUME_CYL(zVolume vol, BOOL bDrawWire, BOOL bDrawFace, INT iSubdivisions)
|
|
VECTOR vUProj
|
|
VECTOR vOffset
|
|
VECTOR vNegOffset
|
|
VECTOR vVertices[iMAX_ZVC_VERTS]
|
|
VECTOR vTopVertexCenter
|
|
VECTOR vBottomVertexCenter
|
|
VECTOR vTopVertexCur
|
|
VECTOR vBottomVertexCur
|
|
VECTOR vTopVertexNext
|
|
VECTOR vBottomVertexNext
|
|
FLOAT fLocalAngle
|
|
FLOAT fSubdivisions = TO_FLOAT(iSubdivisions)
|
|
INT iHalfSubdivisions = iSubdivisions / 2
|
|
INT i
|
|
|
|
// Quit if there's nothing to do.
|
|
IF NOT bDrawWire AND NOT bDrawFace
|
|
EXIT
|
|
ENDIF
|
|
|
|
// Check for valid subdivisions.
|
|
IF iSubdivisions < 3
|
|
SCRIPT_ASSERT("Can't draw a cylinder with less than three subdivisions!")
|
|
EXIT
|
|
ELIF iSubdivisions > iMAX_ZVC_VERTS / 2
|
|
SCRIPT_ASSERT("Too many subdivisions! Check iMAX_ZVC_VERTS and divide by two!")
|
|
EXIT
|
|
ENDIF
|
|
|
|
// Create projection vector.
|
|
vUProj = <<0.0, 0.0, 0.5 * vol.fHeight>>
|
|
|
|
// Generate vertices.
|
|
REPEAT iHalfSubdivisions i
|
|
fLocalAngle = (TO_FLOAT(i) / fSubdivisions) * 360.0
|
|
vOffset = <<COS(fLocalAngle) * 0.5 * vol.fWidth, SIN(fLocalAngle) * 0.5 * vol.fDepth, 0.0>>
|
|
vOffset = ROTATE_VECTOR_ABOUT_Z(vOffset, vol.fRotation)
|
|
vNegOffset = -vOffset
|
|
vOffset += vol.vCenter
|
|
vNegOffset += vol.vCenter
|
|
vVertices[i*2 ] = vOffset + vUProj
|
|
vVertices[i*2+1 ] = vOffset - vUProj
|
|
vVertices[i*2+iSubdivisions ] = vNegOffset + vUProj
|
|
vVertices[i*2+iSubdivisions+1] = vNegOffset - vUProj
|
|
ENDREPEAT
|
|
|
|
vTopVertexCenter = vol.vCenter + vUProj
|
|
vBottomVertexCenter = vol.vCenter - vUProj
|
|
|
|
// Iterate through pie slices and draw wireframe.
|
|
IF bDrawWire
|
|
REPEAT iSubdivisions i
|
|
vTopVertexCur = vVertices[i*2]
|
|
vBottomVertexCur = vVertices[i*2+1]
|
|
IF i < iSubdivisions - 1
|
|
vTopVertexNext = vVertices[i*2+2]
|
|
vBottomVertexNext = vVertices[i*2+3]
|
|
ELSE
|
|
vTopVertexNext = vVertices[0]
|
|
vBottomVertexNext = vVertices[1]
|
|
ENDIF
|
|
|
|
// Draw wireframe for this pie piece.
|
|
DRAW_DEBUG_LINE(vTopVertexCenter, vTopVertexCur, 0, 255, 0, zvw_iAlphaWire)
|
|
DRAW_DEBUG_LINE(vBottomVertexCenter, vBottomVertexCur, 0, 255, 0, zvw_iAlphaWire)
|
|
DRAW_DEBUG_LINE(vTopVertexCur, vBottomVertexCur, 0, 255, 0, zvw_iAlphaWire)
|
|
DRAW_DEBUG_LINE(vTopVertexCur, vTopVertexNext, 0, 255, 0, zvw_iAlphaWire)
|
|
DRAW_DEBUG_LINE(vBottomVertexCur, vBottomVertexNext, 0, 255, 0, zvw_iAlphaWire)
|
|
ENDREPEAT
|
|
ENDIF
|
|
|
|
// Iterate through pie slices and draw faces.
|
|
// Do a separate loop so wireframe does not get culled out.
|
|
IF bDrawFace
|
|
REPEAT iSubdivisions i
|
|
vTopVertexCur = vVertices[i*2]
|
|
vBottomVertexCur = vVertices[i*2+1]
|
|
IF i < iSubdivisions - 1
|
|
vTopVertexNext = vVertices[i*2+2]
|
|
vBottomVertexNext = vVertices[i*2+3]
|
|
ELSE
|
|
vTopVertexNext = vVertices[0]
|
|
vBottomVertexNext = vVertices[1]
|
|
ENDIF
|
|
|
|
// Draw faces for this pie piece.
|
|
DRAW_DEBUG_POLY(vTopVertexCenter, vTopVertexCur, vTopVertexNext, 0, 0, 127, zvw_iAlphaFace)
|
|
DRAW_DEBUG_POLY(vBottomVertexCenter, vBottomVertexNext, vBottomVertexCur, 0, 0, 127, zvw_iAlphaFace)
|
|
DRAW_DEBUG_POLY(vTopVertexCur, vBottomVertexCur, vBottomVertexNext, 0, 0, 127, zvw_iAlphaFace)
|
|
DRAW_DEBUG_POLY(vTopVertexCur, vBottomVertexNext, vTopVertexNext, 0, 0, 127, zvw_iAlphaFace)
|
|
ENDREPEAT
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
// Debug draw for ellipsoid.
|
|
/*PROC DRAW_ZVOLUME_ELD(zVolume vol, BOOL bDrawWire, BOOL bDrawFace)
|
|
zTriangle curTriangle
|
|
FLOAT fSin = SIN(vol.fRotation)
|
|
FLOAT fCos = COS(vol.fRotation)
|
|
INT i
|
|
|
|
// Iterate through triangles to draw wireframe.
|
|
IF bDrawWire
|
|
REPEAT 512 i
|
|
// Scale vertices.
|
|
curTriangle.p1.x = zvw_Triangles[i].p1.x * vol.fWidth
|
|
curTriangle.p1.y = zvw_Triangles[i].p1.y * vol.fDepth
|
|
curTriangle.p1.z = zvw_Triangles[i].p1.z * vol.fHeight
|
|
curTriangle.p2.x = zvw_Triangles[i].p2.x * vol.fWidth
|
|
curTriangle.p2.y = zvw_Triangles[i].p2.y * vol.fDepth
|
|
curTriangle.p2.z = zvw_Triangles[i].p2.z * vol.fHeight
|
|
curTriangle.p3.x = zvw_Triangles[i].p3.x * vol.fWidth
|
|
curTriangle.p3.y = zvw_Triangles[i].p3.y * vol.fDepth
|
|
curTriangle.p3.z = zvw_Triangles[i].p3.z * vol.fHeight
|
|
|
|
// Rotate vertices.
|
|
curTriangle.p1 = ROTATE_VECTOR_ABOUT_Z_PRECOMPUTE(curTriangle.p1, fSin, fCos)
|
|
curTriangle.p2 = ROTATE_VECTOR_ABOUT_Z_PRECOMPUTE(curTriangle.p2, fSin, fCos)
|
|
curTriangle.p3 = ROTATE_VECTOR_ABOUT_Z_PRECOMPUTE(curTriangle.p3, fSin, fCos)
|
|
|
|
// Translate vertices.
|
|
curTriangle.p1 += vol.vCenter
|
|
curTriangle.p2 += vol.vCenter
|
|
curTriangle.p3 += vol.vCenter
|
|
|
|
// Draw wireframe.
|
|
DRAW_DEBUG_LINE(curTriangle.p1, curTriangle.p2, 0, 255, 0, 210)
|
|
DRAW_DEBUG_LINE(curTriangle.p2, curTriangle.p3, 0, 255, 0, 210)
|
|
DRAW_DEBUG_LINE(curTriangle.p3, curTriangle.p1, 0, 255, 0, 210)
|
|
ENDREPEAT
|
|
ENDIF
|
|
|
|
// Iterate through triangles to draw faces.
|
|
// Do this in a separate loop so wireframe doesn't get culled out.
|
|
IF bDrawFace
|
|
REPEAT 512 i
|
|
// Scale vertices.
|
|
curTriangle.p1.x = zvw_Triangles[i].p1.x * vol.fWidth
|
|
curTriangle.p1.y = zvw_Triangles[i].p1.y * vol.fDepth
|
|
curTriangle.p1.z = zvw_Triangles[i].p1.z * vol.fHeight
|
|
curTriangle.p2.x = zvw_Triangles[i].p2.x * vol.fWidth
|
|
curTriangle.p2.y = zvw_Triangles[i].p2.y * vol.fDepth
|
|
curTriangle.p2.z = zvw_Triangles[i].p2.z * vol.fHeight
|
|
curTriangle.p3.x = zvw_Triangles[i].p3.x * vol.fWidth
|
|
curTriangle.p3.y = zvw_Triangles[i].p3.y * vol.fDepth
|
|
curTriangle.p3.z = zvw_Triangles[i].p3.z * vol.fHeight
|
|
|
|
// Rotate vertices.
|
|
curTriangle.p1 = ROTATE_VECTOR_ABOUT_Z_PRECOMPUTE(curTriangle.p1, fSin, fCos)
|
|
curTriangle.p2 = ROTATE_VECTOR_ABOUT_Z_PRECOMPUTE(curTriangle.p2, fSin, fCos)
|
|
curTriangle.p3 = ROTATE_VECTOR_ABOUT_Z_PRECOMPUTE(curTriangle.p3, fSin, fCos)
|
|
|
|
// Translate vertices.
|
|
curTriangle.p1 += vol.vCenter
|
|
curTriangle.p2 += vol.vCenter
|
|
curTriangle.p3 += vol.vCenter
|
|
|
|
// Draw face.
|
|
DRAW_DEBUG_POLY(curTriangle.p1, curTriangle.p2, curTriangle.p3, 0, 0, 127, 127)
|
|
ENDREPEAT
|
|
ENDIF
|
|
ENDPROC
|
|
*/
|
|
// Draw the endpoints for an angled area.
|
|
PROC DRAW_ANGAREA_ENDPOINTS()
|
|
DRAW_DEBUG_SPHERE(zvw_vAngMidpt1, 0.3, 255, 0, 0)
|
|
DRAW_DEBUG_SPHERE(zvw_vAngMidpt2, 0.3, 255, 0, 0)
|
|
ENDPROC
|
|
|
|
// Generate base vertices to use for ellipsoid drawing.
|
|
/*PROC GENERATE_NSPHERE()
|
|
VECTOR vOctahedron[6]
|
|
VECTOR vMidpt1, vMidpt2, vMidpt3
|
|
INT iIteration, i, iTriangles, iTrianglesLast
|
|
|
|
// Start with a uniform octahedron.
|
|
vOctahedron[0] = << 0.0, 0.0, 0.5>>
|
|
vOctahedron[1] = << 0.0, 0.0, -0.5>>
|
|
vOctahedron[2] = << 0.0, -0.5, 0.0>>
|
|
vOctahedron[3] = << 0.5, 0.0, 0.0>>
|
|
vOctahedron[4] = << 0.0, 0.5, 0.0>>
|
|
vOctahedron[5] = <<-0.5, 0.0, 0.0>>
|
|
|
|
// Assign verts to the triangles.
|
|
zvw_Triangles[0].p1 = vOctahedron[0]
|
|
zvw_Triangles[0].p2 = vOctahedron[3]
|
|
zvw_Triangles[0].p3 = vOctahedron[4]
|
|
zvw_Triangles[1].p1 = vOctahedron[0]
|
|
zvw_Triangles[1].p2 = vOctahedron[4]
|
|
zvw_Triangles[1].p3 = vOctahedron[5]
|
|
zvw_Triangles[2].p1 = vOctahedron[0]
|
|
zvw_Triangles[2].p2 = vOctahedron[5]
|
|
zvw_Triangles[2].p3 = vOctahedron[2]
|
|
zvw_Triangles[3].p1 = vOctahedron[0]
|
|
zvw_Triangles[3].p2 = vOctahedron[2]
|
|
zvw_Triangles[3].p3 = vOctahedron[3]
|
|
zvw_Triangles[4].p1 = vOctahedron[1]
|
|
zvw_Triangles[4].p2 = vOctahedron[4]
|
|
zvw_Triangles[4].p3 = vOctahedron[3]
|
|
zvw_Triangles[5].p1 = vOctahedron[1]
|
|
zvw_Triangles[5].p2 = vOctahedron[5]
|
|
zvw_Triangles[5].p3 = vOctahedron[4]
|
|
zvw_Triangles[6].p1 = vOctahedron[1]
|
|
zvw_Triangles[6].p2 = vOctahedron[2]
|
|
zvw_Triangles[6].p3 = vOctahedron[5]
|
|
zvw_Triangles[7].p1 = vOctahedron[1]
|
|
zvw_Triangles[7].p2 = vOctahedron[3]
|
|
zvw_Triangles[7].p3 = vOctahedron[2]
|
|
|
|
iTriangles = 8
|
|
|
|
// Perform three additional subdivisions.
|
|
REPEAT 3 iIteration
|
|
iTrianglesLast = iTriangles
|
|
|
|
// Iterate through our current triangles.
|
|
REPEAT iTrianglesLast i
|
|
// Generate midpoints along edges and place them on the sphere's surface.
|
|
vMidpt1 = (zvw_Triangles[i].p1 + zvw_Triangles[i].p2) / 2.0
|
|
vMidpt2 = (zvw_Triangles[i].p2 + zvw_Triangles[i].p3) / 2.0
|
|
vMidpt3 = (zvw_Triangles[i].p3 + zvw_Triangles[i].p1) / 2.0
|
|
vMidpt1 = GET_VECTOR_OF_LENGTH(vMidpt1, 0.5)
|
|
vMidpt2 = GET_VECTOR_OF_LENGTH(vMidpt2, 0.5)
|
|
vMidpt3 = GET_VECTOR_OF_LENGTH(vMidpt3, 0.5)
|
|
|
|
// Assign verts to triangles.
|
|
zvw_Triangles[iTriangles].p1 = zvw_Triangles[i].p1
|
|
zvw_Triangles[iTriangles].p2 = vMidpt1
|
|
zvw_Triangles[iTriangles].p3 = vMidpt3
|
|
++iTriangles
|
|
zvw_Triangles[iTriangles].p1 = vMidpt1
|
|
zvw_Triangles[iTriangles].p2 = zvw_Triangles[i].p2
|
|
zvw_Triangles[iTriangles].p3 = vMidpt2
|
|
++iTriangles
|
|
zvw_Triangles[iTriangles].p1 = vMidpt2
|
|
zvw_Triangles[iTriangles].p2 = zvw_Triangles[i].p3
|
|
zvw_Triangles[iTriangles].p3 = vMidpt3
|
|
++iTriangles
|
|
zvw_Triangles[i].p1 = vMidpt1
|
|
zvw_Triangles[i].p2 = vMidpt2
|
|
zvw_Triangles[i].p3 = vMidpt3
|
|
ENDREPEAT
|
|
ENDREPEAT
|
|
ENDPROC
|
|
*/
|
|
// Set up the widgets for editing volumes.
|
|
PROC INIT_ZVOLUME_WIDGETS()
|
|
IF zvw_bInit
|
|
EXIT
|
|
ENDIF
|
|
zvw_bInit = TRUE
|
|
|
|
zvw_fPosX = 0.0
|
|
zvw_fPosY = 0.0
|
|
zvw_fPosZ = 0.0
|
|
zvw_fDimX = 5.0
|
|
zvw_fDimY = 5.0
|
|
zvw_fDimZ = 4.0
|
|
zvw_fRotZ = 0.0
|
|
zvw_bPosSnapPlr = FALSE
|
|
zvw_bRotSnapPlr = FALSE
|
|
zvw_bPosSnapCam = FALSE
|
|
zvw_bRotSnapCam = FALSE
|
|
zvw_bPosSnapOrg = FALSE
|
|
zvw_bRotSnapOrg = FALSE
|
|
zvw_bDefaultDim = FALSE
|
|
zvw_bDrawMaster = FALSE
|
|
zvw_bDrawAsRec = TRUE
|
|
zvw_bDrawAsCyl = FALSE
|
|
zvw_bDrawAsEld = FALSE
|
|
zvw_iSubdiv = 20
|
|
zvw_bDrawWire = TRUE
|
|
zvw_iAlphaWire = 210
|
|
zvw_bDrawFace = TRUE
|
|
zvw_iAlphaFace = 127
|
|
zvw_bDoCollision = FALSE
|
|
zvw_bVolCheckPlr = FALSE
|
|
zvw_bVolCheckCam = FALSE
|
|
|
|
zvw_iMode = 0
|
|
|
|
zvw_Volume.vCenter.x = zvw_fPosX
|
|
zvw_Volume.vCenter.y = zvw_fPosY
|
|
zvw_Volume.vCenter.z = zvw_fPosZ
|
|
zvw_Volume.fWidth = zvw_fDimX
|
|
zvw_Volume.fDepth = zvw_fDimY
|
|
zvw_Volume.fHeight = zvw_fDimZ
|
|
zvw_Volume.fRotation = zvw_fRotZ
|
|
|
|
zvw_zVolumeWidgets = START_WIDGET_GROUP("Z-Aligned Volumes")
|
|
|
|
zvw_posDimGroup = START_WIDGET_GROUP("Position and Dimensions")
|
|
ADD_WIDGET_FLOAT_SLIDER("Position x" , zvw_fPosX, -3300.0, 4300.0, 100.0)
|
|
ADD_WIDGET_FLOAT_SLIDER("Position y" , zvw_fPosY, -3800.0, 4200.0, 100.0)
|
|
ADD_WIDGET_FLOAT_SLIDER("Position z" , zvw_fPosZ, -200.0, 600.0, 15.0)
|
|
ADD_WIDGET_FLOAT_SLIDER("Width (x)" , zvw_fDimX, 0.0, 1000.0, 10.0)
|
|
ADD_WIDGET_FLOAT_SLIDER("Depth (y)" , zvw_fDimY, 0.0, 1000.0, 10.0)
|
|
ADD_WIDGET_FLOAT_SLIDER("Height (z)" , zvw_fDimZ, 0.0, 600.0, 6.0)
|
|
ADD_WIDGET_FLOAT_SLIDER("Rotation (z)", zvw_fRotZ, 0.0, 360.0, 3.6)
|
|
ADD_WIDGET_BOOL("Snap position to player", zvw_bPosSnapPlr)
|
|
ADD_WIDGET_BOOL("Snap rotation to player", zvw_bRotSnapPlr)
|
|
ADD_WIDGET_BOOL("Snap position to camera", zvw_bPosSnapCam)
|
|
ADD_WIDGET_BOOL("Snap rotation to camera", zvw_bRotSnapCam)
|
|
ADD_WIDGET_BOOL("Snap position to origin", zvw_bPosSnapOrg)
|
|
ADD_WIDGET_BOOL("Snap rotation to origin", zvw_bRotSnapOrg)
|
|
ADD_WIDGET_BOOL("Reset to default dimensions", zvw_bDefaultDim)
|
|
STOP_WIDGET_GROUP()
|
|
|
|
zvw_renderingGroup = START_WIDGET_GROUP("Rendering")
|
|
ADD_WIDGET_BOOL("Draw (master)" , zvw_bDrawMaster)
|
|
ADD_WIDGET_BOOL("Render as rectangular prism" , zvw_bDrawAsRec)
|
|
ADD_WIDGET_BOOL("Render as elliptic cylinder (not supported)" , zvw_bDrawAsCyl)
|
|
ADD_WIDGET_BOOL("Render as elliptoid (not supported)" , zvw_bDrawAsEld)
|
|
ADD_WIDGET_INT_SLIDER("Subdivisions (cyl)", zvw_iSubdiv, 4, iMAX_ZVC_VERTS / 2, 2)
|
|
ADD_WIDGET_BOOL("Draw wireframe", zvw_bDrawWire)
|
|
ADD_WIDGET_INT_SLIDER("Wireframe alpha", zvw_iAlphaWire, 0, 255, 2)
|
|
ADD_WIDGET_BOOL("Draw faces", zvw_bDrawFace)
|
|
ADD_WIDGET_INT_SLIDER("Face alpha", zvw_iAlphaFace, 0, 255, 2)
|
|
STOP_WIDGET_GROUP()
|
|
|
|
zvw_collisionGroup = START_WIDGET_GROUP("Collision Checks")
|
|
ADD_WIDGET_BOOL("Peform collision checks", zvw_bDoCollision)
|
|
ADD_WIDGET_BOOL("Player in volume", zvw_bVolCheckPlr)
|
|
ADD_WIDGET_BOOL("Camera in volume", zvw_bVolCheckCam)
|
|
STOP_WIDGET_GROUP()
|
|
|
|
zvw_angledAreaGroup = START_WIDGET_GROUP("Angled Area")
|
|
ADD_WIDGET_FLOAT_READ_ONLY("Point 1 x", zvw_fAngMidpt1x)
|
|
ADD_WIDGET_FLOAT_READ_ONLY("Point 1 y", zvw_fAngMidpt1y)
|
|
ADD_WIDGET_FLOAT_READ_ONLY("Point 1 z", zvw_fAngMidpt1z)
|
|
ADD_WIDGET_FLOAT_READ_ONLY("Point 2 x", zvw_fAngMidpt2x)
|
|
ADD_WIDGET_FLOAT_READ_ONLY("Point 2 y", zvw_fAngMidpt2y)
|
|
ADD_WIDGET_FLOAT_READ_ONLY("Point 2 z", zvw_fAngMidpt2z)
|
|
ADD_WIDGET_FLOAT_READ_ONLY("Width", zvw_fAngWidth)
|
|
STOP_WIDGET_GROUP()
|
|
|
|
STOP_WIDGET_GROUP()
|
|
|
|
// Generate base triangles for ellipsoids.
|
|
//GENERATE_NSPHERE()
|
|
ENDPROC
|
|
|
|
// Use to destroy widgets.
|
|
PROC CLEANUP_ZVOLUME_WIDGETS()
|
|
IF DOES_WIDGET_GROUP_EXIST(zvw_angledAreaGroup)
|
|
DELETE_WIDGET_GROUP(zvw_angledAreaGroup)
|
|
ENDIF
|
|
IF DOES_WIDGET_GROUP_EXIST(zvw_collisionGroup)
|
|
DELETE_WIDGET_GROUP(zvw_collisionGroup)
|
|
ENDIF
|
|
IF DOES_WIDGET_GROUP_EXIST(zvw_renderingGroup)
|
|
DELETE_WIDGET_GROUP(zvw_renderingGroup)
|
|
ENDIF
|
|
IF DOES_WIDGET_GROUP_EXIST(zvw_posDimGroup)
|
|
DELETE_WIDGET_GROUP(zvw_posDimGroup)
|
|
ENDIF
|
|
IF DOES_WIDGET_GROUP_EXIST(zvw_zVolumeWidgets)
|
|
DELETE_WIDGET_GROUP(zvw_zVolumeWidgets)
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
// Call once per frame so widgets work.
|
|
PROC UPDATE_ZVOLUME_WIDGETS()
|
|
VECTOR vPlayerPos
|
|
VECTOR vCameraPos
|
|
VECTOR vCameraRot
|
|
FLOAT fPlayerHeading
|
|
CAMERA_INDEX curCam
|
|
|
|
// Perform one-time init.
|
|
IF NOT zvw_bInit
|
|
INIT_ZVOLUME_WIDGETS()
|
|
ENDIF
|
|
|
|
IF NOT IS_PED_INJURED(PLAYER_PED_ID())
|
|
vPlayerPos = GET_ENTITY_COORDS(PLAYER_PED_ID())
|
|
fPlayerHeading = GET_ENTITY_HEADING(PLAYER_PED_ID())
|
|
ENDIF
|
|
curCam = GET_RENDERING_CAM()
|
|
IF DOES_CAM_EXIST(curCam)
|
|
vCameraPos = GET_CAM_COORD(curCam)
|
|
vCameraRot = GET_CAM_ROT(curCam)
|
|
ELSE
|
|
vCameraPos = GET_GAMEPLAY_CAM_COORD()
|
|
vCameraRot = GET_GAMEPLAY_CAM_ROT()
|
|
ENDIF
|
|
|
|
// Snap to player position.
|
|
IF zvw_bPosSnapPlr
|
|
zvw_fPosX = vPlayerPos.x
|
|
zvw_fPosY = vPlayerPos.y
|
|
zvw_fPosZ = vPlayerPos.z
|
|
zvw_bPosSnapPlr = FALSE
|
|
ENDIF
|
|
|
|
// Snap to player rotation.
|
|
IF zvw_bRotSnapPlr
|
|
zvw_fRotZ = fPlayerHeading
|
|
zvw_bRotSnapPlr = FALSE
|
|
ENDIF
|
|
|
|
// Snap to camera position.
|
|
IF zvw_bPosSnapCam
|
|
zvw_fPosX = vCameraPos.x
|
|
zvw_fPosY = vCameraPos.y
|
|
zvw_fPosZ = vCameraPos.z
|
|
zvw_bPosSnapCam = FALSE
|
|
ENDIF
|
|
|
|
// Snap to camera rotation.
|
|
IF zvw_bRotSnapCam
|
|
zvw_fRotZ = vCameraRot.z
|
|
zvw_bRotSnapCam = FALSE
|
|
ENDIF
|
|
|
|
// Snap to origin.
|
|
IF zvw_bPosSnapOrg
|
|
zvw_fPosX = 0.0
|
|
zvw_fPosY = 0.0
|
|
zvw_fPosZ = 0.0
|
|
zvw_bPosSnapOrg = FALSE
|
|
ENDIF
|
|
|
|
// Zero out rotation.
|
|
IF zvw_bRotSnapOrg
|
|
zvw_fRotZ = 0.0
|
|
zvw_bRotSnapOrg = FALSE
|
|
ENDIF
|
|
|
|
// Back to default dimensions.
|
|
IF zvw_bDefaultDim
|
|
zvw_fDimX = 5.0
|
|
zvw_fDimY = 5.0
|
|
zvw_fDimZ = 4.0
|
|
zvw_bDefaultDim = FALSE
|
|
ENDIF
|
|
|
|
// Switch to rectangular prism mode.
|
|
IF zvw_bDrawAsRec
|
|
IF zvw_iMode <> 0
|
|
zvw_iMode = 0
|
|
zvw_bDrawAsCyl = FALSE
|
|
zvw_bDrawAsEld = FALSE
|
|
ENDIF
|
|
ENDIF
|
|
|
|
// Switch to elliptic cylinder mode.
|
|
IF zvw_bDrawAsCyl
|
|
IF zvw_iMode <> 1
|
|
zvw_iMode = 1
|
|
zvw_bDrawAsRec = FALSE
|
|
zvw_bDrawAsEld = FALSE
|
|
ENDIF
|
|
ENDIF
|
|
|
|
// Switch to elliptoid mode.
|
|
IF zvw_bDrawAsEld
|
|
zvw_bDrawAsEld = FALSE
|
|
IF zvw_iMode <> 2
|
|
zvw_iMode = 2
|
|
zvw_bDrawAsRec = FALSE
|
|
zvw_bDrawAsCyl = FALSE
|
|
ENDIF
|
|
ENDIF
|
|
|
|
// Make sure one mode is selected.
|
|
IF NOT zvw_bDrawAsRec
|
|
AND NOT zvw_bDrawAsCyl
|
|
AND NOT zvw_bDrawAsEld
|
|
IF zvw_iMode = 0
|
|
zvw_bDrawAsRec = TRUE
|
|
ELIF zvw_iMode = 1
|
|
zvw_bDrawAsCyl = TRUE
|
|
ELSE
|
|
zvw_bDrawAsEld = TRUE
|
|
ENDIF
|
|
ENDIF
|
|
|
|
// Clamp subdivisions to an even number.
|
|
IF IS_BIT_SET(zvw_iSubdiv, 0)
|
|
zvw_iSubdiv = IMAX(zvw_iSubdiv - 1, 4)
|
|
ENDIF
|
|
|
|
// Update internal volume.
|
|
zvw_Volume.vCenter.x = zvw_fPosX
|
|
zvw_Volume.vCenter.y = zvw_fPosY
|
|
zvw_Volume.vCenter.z = zvw_fPosZ
|
|
zvw_Volume.fWidth = zvw_fDimX
|
|
zvw_Volume.fDepth = zvw_fDimY
|
|
zvw_Volume.fHeight = zvw_fDimZ
|
|
zvw_Volume.fRotation = zvw_fRotZ
|
|
|
|
// Update angled area stats.
|
|
IF zvw_bDrawAsRec
|
|
GET_ANGLED_AREA_FROM_ZVOLUME(zvw_Volume, zvw_vAngMidpt1, zvw_vAngMidpt2, zvw_fAngWidth)
|
|
zvw_fAngMidpt1x = zvw_vAngMidpt1.x
|
|
zvw_fAngMidpt1y = zvw_vAngMidpt1.y
|
|
zvw_fAngMidpt1z = zvw_vAngMidpt1.z
|
|
zvw_fAngMidpt2x = zvw_vAngMidpt2.x
|
|
zvw_fAngMidpt2y = zvw_vAngMidpt2.y
|
|
zvw_fAngMidpt2z = zvw_vAngMidpt2.z
|
|
ELSE
|
|
zvw_vAngMidpt1 = <<0.0,0.0,0.0>>
|
|
zvw_vAngMidpt2 = <<0.0,0.0,0.0>>
|
|
zvw_fAngMidpt1x = 0.0
|
|
zvw_fAngMidpt1y = 0.0
|
|
zvw_fAngMidpt1z = 0.0
|
|
zvw_fAngMidpt2x = 0.0
|
|
zvw_fAngMidpt2y = 0.0
|
|
zvw_fAngMidpt2z = 0.0
|
|
zvw_fAngWidth = 0.0
|
|
ENDIF
|
|
|
|
// Perform collision checks.
|
|
IF zvw_bDoCollision
|
|
IF zvw_bDrawAsRec
|
|
zvw_bVolCheckPlr = IS_ENTITY_IN_ANGLED_AREA(PLAYER_PED_ID(), zvw_vAngMidpt1, zvw_vAngMidpt2, zvw_fAngWidth, TRUE, FALSE)
|
|
zvw_bVolCheckCam = IS_POINT_IN_ANGLED_AREA(vCameraPos, zvw_vAngMidpt1, zvw_vAngMidpt2, zvw_fAngWidth, FALSE, FALSE)
|
|
// ELIF zvw_bDrawAsCyl
|
|
// zvw_bVolCheckPlr = IS_ENTITY_IN_CYLINDER(PLAYER_PED_ID(), GET_ZVOLUME_BOTTOM(zvw_Volume), zvw_Volume.fWidth, zvw_Volume.fDepth, zvw_Volume.fHeight, zvw_Volume.fRotation, TRUE)
|
|
// zvw_bVolCheckCam = IS_POINT_IN_CYLINDER(vCameraPos, GET_ZVOLUME_BOTTOM(zvw_Volume), zvw_Volume.fWidth, zvw_Volume.fDepth, zvw_Volume.fHeight, zvw_Volume.fRotation, TRUE)
|
|
ELSE
|
|
zvw_bVolCheckPlr = FALSE
|
|
zvw_bVolCheckCam = FALSE
|
|
// zvw_bVolCheckPlr = IS_ENTITY_IN_ELLIPSOID(PLAYER_PED_ID(), zvw_Volume.vCenter, zvw_Volume.fWidth, zvw_Volume.fDepth, zvw_Volume.fHeight, zvw_Volume.fRotation)
|
|
// zvw_bVolCheckCam = IS_POINT_IN_ELLIPSOID(vCameraPos, zvw_Volume.vCenter, zvw_Volume.fWidth, zvw_Volume.fDepth, zvw_Volume.fHeight, zvw_Volume.fRotation)
|
|
ENDIF
|
|
ELSE
|
|
zvw_bVolCheckPlr = FALSE
|
|
zvw_bVolCheckCam = FALSE
|
|
ENDIF
|
|
|
|
// Check the master draw switch.
|
|
IF NOT zvw_bDrawMaster
|
|
EXIT
|
|
ENDIF
|
|
|
|
// Perform draw.
|
|
IF zvw_bDrawAsRec
|
|
DRAW_ANGAREA_ENDPOINTS()
|
|
DRAW_ZVOLUME_REC(zvw_Volume, zvw_bDrawWire, zvw_bDrawFace)
|
|
ELIF zvw_bDrawAsCyl
|
|
DRAW_ZVOLUME_CYL(zvw_Volume, zvw_bDrawWire, zvw_bDrawFace, zvw_iSubdiv)
|
|
ELSE
|
|
//DRAW_ZVOLUME_ELD(zvw_Volume, zvw_bDrawWire, zvw_bDrawFace)
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
|
|
#ENDIF // IS_DEBUG_BUILD
|