Files
2025-09-29 00:52:08 +02:00

279 lines
7.0 KiB
Plaintext
Executable File

struct LocalityEntryAxis
(
Negative = #(),
Positive = #(),
fn Dispose =
(
for Direction in #( this.Negative, this.Positive ) do
(
for Element in Direction do
(
if( ClassOf Element == LocalityEntryAxis ) then
(
Element.Dispose()
)
)
Free Direction
)
),
fn GetAllEntries =
(
MasterEntryList = #()
for Direction in #( this.Negative, this.Positive ) do
(
for Element in Direction do
(
if( Element != Undefined )then
(
if( ClassOf Element == LocalityEntryAxis ) then
(
CurrentEntryList = Element.GetAllEntries()
Join MasterEntryList CurrentEntryList
)
else
(
Join MasterEntryList Element
)
)
)
)
return MasterEntryList
)
)
--Stores any form of data using positions as locality keys. This is useful for matching points from one mesh too many meshes.
--http://en.wikipedia.org/wiki/Locality-sensitive_hashing
struct LocalityData
(
--Bucket size in metres (greatly effects memory and speed)
BucketSize = 3.5,
OffsetPositionList = #([0,0,0]),
--Base entry axis
XEntryAxis = LocalityEntryAxis(),
/*------------------------------------------------------------------------------
Gets the key for the passed value based off the current BucketSize
*/------------------------------------------------------------------------------
fn GetEntryKey InputValue =
(
ReturnValue = ( Ceil ( Abs ( InputValue ) / BucketSize ) ) as Integer
if( ReturnValue != 0 ) then
(
return ReturnValue
)
else
(
return 1
)
),
/*------------------------------------------------------------------------------
Adds the passed InputValue into this locality data set using InputPosition as the key
*/------------------------------------------------------------------------------
fn AddEntry InputPosition InputValue =
(
--Get X axis direction
XEntryAxisDirection
if( InputPosition.X > 0 ) then
( XEntryAxisDirection = XEntryAxis.Positive )
else
( XEntryAxisDirection = XEntryAxis.Negative )
--Get Y axis
XKey = this.GetEntryKey InputPosition.X
YEntryAxis = XEntryAxisDirection[XKey]
if( YEntryAxis == Undefined) then
(
YEntryAxis = LocalityEntryAxis()
XEntryAxisDirection[XKey] = YEntryAxis
)
--Get Y axis direction
YEntryAxisDirection
if( InputPosition.Y > 0 ) then
( YEntryAxisDirection = YEntryAxis.Positive )
else
( YEntryAxisDirection = YEntryAxis.Negative )
--Get Z axis
YKey = this.GetEntryKey InputPosition.Y
ZEntryAxis = YEntryAxisDirection[YKey]
if( ZEntryAxis == Undefined) then
(
ZEntryAxis = LocalityEntryAxis()
YEntryAxisDirection[YKey] = ZEntryAxis
)
--Get Z axis direction
ZEntryAxisDirection
if( InputPosition.Z > 0 ) then
( ZEntryAxisDirection = ZEntryAxis.Positive )
else
( ZEntryAxisDirection = ZEntryAxis.Negative )
--Set Value ---------------------------
ZKey = this.GetEntryKey InputPosition.Z
if( ZEntryAxisDirection[ZKey] == Undefined ) then
(
ZEntryAxisDirection[ZKey] = #( DataPair Position:InputPosition Value:InputValue )
)
else
(
Append ZEntryAxisDirection[ZKey] ( DataPair Position:InputPosition Value:InputValue )
)
),
/*------------------------------------------------------------------------------
Gets the value for the closest entry based of the passed InputPosition
*/------------------------------------------------------------------------------
fn GetBucketEntries InputPosition =
(
--Get X axis direction
XEntryAxisDirection
if( InputPosition.X > 0 ) then
( XEntryAxisDirection = XEntryAxis.Positive )
else
( XEntryAxisDirection = XEntryAxis.Negative )
--Get Y axis
XKey = this.GetEntryKey InputPosition.X
YEntryAxis = XEntryAxisDirection[XKey]
if( YEntryAxis == Undefined) then
(
return Undefined
)
--Get Y axis direction
YEntryAxisDirection
if( InputPosition.Y > 0 ) then
( YEntryAxisDirection = YEntryAxis.Positive )
else
( YEntryAxisDirection = YEntryAxis.Negative )
--Get Z axis
YKey = this.GetEntryKey InputPosition.Y
ZEntryAxis = YEntryAxisDirection[YKey]
if( ZEntryAxis == Undefined) then
(
return Undefined
)
--Get Z axis direction
ZEntryAxisDirection
if( InputPosition.Z > 0 ) then
( ZEntryAxisDirection = ZEntryAxis.Positive )
else
( ZEntryAxisDirection = ZEntryAxis.Negative )
--Get Value ---------------------------
ZKey = this.GetEntryKey InputPosition.Z
if( ZEntryAxisDirection[ZKey] == Undefined ) then
(
return Undefined
)
else
(
return ZEntryAxisDirection[ZKey]
)
),
/*------------------------------------------------------------------------------
Gets closest entry to the passed position
*/------------------------------------------------------------------------------
fn GetClosestEntry InputPosition =
(
EntryList = this.GetEntries InputPosition
ClosestEntry = Undefined
for Entry in EntryList do
(
if( ClosestEntry == Undefined ) then
(
EntryDistance = Distance Entry.Position InputPosition
ClosestEntry = DataPair Entry:Entry Distance:EntryDistance
)
else
(
EntryDistance = Distance Entry.Position InputPosition
if( EntryDistance < ClosestEntry.Distance ) then
(
ClosestEntry = DataPair Entry:Entry Distance:EntryDistance
)
)
)
if( ClosestEntry != Undefined ) then
(
return ClosestEntry.Entry
)
else
(
return Undefined
)
),
/*------------------------------------------------------------------------------
Returns all the entries for the passed positions. Will also check surrounding buckets
*/------------------------------------------------------------------------------
fn GetEntries InputPosition =
(
EntryList = #()
for OffsetPosition in OffsetPositionList do
(
CurrentEntryList = this.GetBucketEntries( InputPosition + OffsetPosition )
if( CurrentEntryList != Undefined ) then
(
Join EntryList CurrentEntryList
)
)
return EntryList
),
fn GetAllEntries =
(
EntryList = XEntryAxis.GetAllEntries()
),
/*------------------------------------------------------------------------------
Disposes of all resources related to this instances
*/------------------------------------------------------------------------------
fn Dispose =
(
XEntryAxis.Dispose()
--GC
try ( GC() ) catch ()
try ( GC() ) catch ()
try ( GC() ) catch ()
try ( GC() ) catch ()
try ( GC() ) catch ()
),
fn SetBucketSearchBreadth InputBucketBreadth =
(
OffsetList = #()
for i = 0 to InputBucketBreadth do
(
AppendIfUnique OffsetList ( this.BucketSize * i )
AppendIfUnique OffsetList ( this.BucketSize * -i )
)
this.OffsetPositionList = #()
for OffsetX in OffsetList do
(
for OffsetY in OffsetList do
(
for OffsetZ in OffsetList do
(
Append this.OffsetPositionList ( [ OffsetX, OffsetY, OffsetZ ] )
)
)
)
)
)