94 lines
2.0 KiB
C#
94 lines
2.0 KiB
C#
![]() |
using System.Collections;
|
||
|
using System.Collections.Generic;
|
||
|
using Godot;
|
||
|
using System;
|
||
|
|
||
|
using System.Threading.Tasks;
|
||
|
|
||
|
namespace Rokojori.PointClouds
|
||
|
{
|
||
|
public class PointCloudOcTree:OcTree<Point>
|
||
|
{
|
||
|
List<Vector3> compressedNormals = new List<Vector3>()
|
||
|
{
|
||
|
Vector3.Up,
|
||
|
Vector3.Down,
|
||
|
Vector3.Forward,
|
||
|
Vector3.Back,
|
||
|
Vector3.Right,
|
||
|
Vector3.Left
|
||
|
};
|
||
|
|
||
|
public bool normalSeperation = false;
|
||
|
|
||
|
public PointCloudOcTree( Vector3 min, Vector3 max, float rootCellSize, int maxDepth )
|
||
|
:base( null, min, max, rootCellSize, maxDepth )
|
||
|
{
|
||
|
this._getPosition = GetPointPosition;
|
||
|
this._combinePoints = CombinePoints;
|
||
|
this._smoothPoints = SmoothPoints;
|
||
|
}
|
||
|
|
||
|
protected Vector3 GetPointPosition( Point p )
|
||
|
{
|
||
|
return p.position;
|
||
|
}
|
||
|
|
||
|
protected int GetNormalIndex( Vector3 normal )
|
||
|
{
|
||
|
var closest = -1;
|
||
|
var closestDistance = 100f;
|
||
|
|
||
|
for ( int i = 0; i < compressedNormals.Count; i++ )
|
||
|
{
|
||
|
var d = compressedNormals[ i ].DistanceSquaredTo( normal );
|
||
|
|
||
|
if ( d < closestDistance )
|
||
|
{
|
||
|
closestDistance = d;
|
||
|
closest = i;
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
return closest;
|
||
|
|
||
|
}
|
||
|
|
||
|
protected List<Point> CombinePoints( List<Point> points )
|
||
|
{
|
||
|
if ( normalSeperation )
|
||
|
{
|
||
|
var lists = compressedNormals.Map( c => new List<Point>() );
|
||
|
|
||
|
points.ForEach(
|
||
|
( p )=>
|
||
|
{
|
||
|
var normalIndex = GetNormalIndex( p.normal );
|
||
|
lists[ normalIndex ].Add( p );
|
||
|
}
|
||
|
);
|
||
|
|
||
|
lists = lists.Filter( n => n.Count > 0 );
|
||
|
|
||
|
|
||
|
return lists.Map( l => Point.AsAverage( l ) );
|
||
|
}
|
||
|
|
||
|
return new List<Point>(){ Point.AsAverage( points ) };
|
||
|
}
|
||
|
|
||
|
protected List<Point> SmoothPoints( List<Point> targets, List<Point> points, float amount )
|
||
|
{
|
||
|
if ( targets == null || points == null )
|
||
|
{
|
||
|
return targets;
|
||
|
}
|
||
|
|
||
|
var average = Point.AsAverage( points );
|
||
|
return targets.Map( t => t.Lerp( average, amount ) );;
|
||
|
}
|
||
|
|
||
|
|
||
|
}
|
||
|
}
|