279 lines
7.0 KiB
Plaintext
Executable File
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 ] )
|
|
)
|
|
)
|
|
)
|
|
)
|
|
|
|
) |