Major progress in introducing arbitrary boundaries! EDT in the house.
This commit is contained in:
@@ -4,6 +4,7 @@
|
||||
package fluid
|
||||
|
||||
import (
|
||||
"fluids/edt"
|
||||
"fluids/utils"
|
||||
"math"
|
||||
)
|
||||
@@ -41,6 +42,9 @@ type Fluid struct {
|
||||
flipPicRatio float32
|
||||
numSubSteps int //number of simulation substeps
|
||||
Block bool //rectangular or circular field container
|
||||
|
||||
//for arbitrary boundaries
|
||||
edt *edt.EDT
|
||||
}
|
||||
|
||||
func NewFluid(dimensions FieldVector, spacing float32) *Fluid {
|
||||
@@ -52,6 +56,7 @@ func NewFluid(dimensions FieldVector, spacing float32) *Fluid {
|
||||
flipPicRatio: FluidDefaultFlipPicRatio,
|
||||
numSubSteps: FluidDefaultSubSteps,
|
||||
Block: true,
|
||||
edt: nil,
|
||||
}
|
||||
|
||||
f.Initialize()
|
||||
@@ -268,6 +273,11 @@ func (f *Fluid) HandleParticleCollisions() {
|
||||
minDist2 := minDist * minDist
|
||||
*/
|
||||
|
||||
if f.edt != nil {
|
||||
f.HandleBoundaryCollisions()
|
||||
return
|
||||
}
|
||||
|
||||
if f.Block {
|
||||
minX := f.Field.H + f.particleRadius
|
||||
maxX := float32(f.Field.Nx-1)*f.Field.H - f.particleRadius
|
||||
@@ -651,3 +661,53 @@ func (f *Fluid) SolveIncompressibility() {
|
||||
func (f *Fluid) ToggleShape() {
|
||||
f.Block = !f.Block
|
||||
}
|
||||
|
||||
func (f *Fluid) SetBoundary(b *Boundary) {
|
||||
|
||||
if b != nil {
|
||||
dim := edt.Bounds{
|
||||
X: b.Dimensions.X,
|
||||
Y: b.Dimensions.Y,
|
||||
}
|
||||
|
||||
f.edt = edt.NewEDT(dim)
|
||||
f.edt.AssignOccupancy(b.Cells)
|
||||
f.edt.ComputeDistanceTransform()
|
||||
} else {
|
||||
f.edt = nil
|
||||
}
|
||||
}
|
||||
|
||||
// we perform our boundary resolution on particles according to our defined fluid boundary
|
||||
func (f *Fluid) HandleBoundaryCollisions() {
|
||||
|
||||
//grid spacing within our distance field
|
||||
dx := f.Field.Dimensions.X / float32(f.edt.Dimensions.X)
|
||||
dy := f.Field.Dimensions.Y / float32(f.edt.Dimensions.Y)
|
||||
|
||||
//find cell of distance field for which particles belong, check if it's in bounds
|
||||
for i := range f.Particles {
|
||||
p := &f.Particles[i]
|
||||
|
||||
xi := utils.Clamp(int(math.Floor(float64(p.Position.X/dx))), 0, f.edt.Dimensions.X-1)
|
||||
yi := utils.Clamp(int(math.Floor(float64(p.Position.Y/dy))), 0, f.edt.Dimensions.Y-1)
|
||||
|
||||
cellidx := xi + yi*f.edt.Dimensions.X
|
||||
|
||||
//if our current cell isn't a boundary, then we skip
|
||||
if f.edt.D[cellidx] == 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
//find where the particle actually belongs
|
||||
pos := f.edt.L[cellidx]
|
||||
newx := (float32(pos.X-xi) + f.particleRadius) * dx
|
||||
newy := (float32(pos.Y-yi) + f.particleRadius) * dy
|
||||
p.Position.X += newx
|
||||
p.Position.Y += newy
|
||||
p.Velocity.X = 0
|
||||
p.Velocity.Y = 0
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user