Added grid render.

Added particle toggle.
Added boundary shape adjustment.
This commit is contained in:
2025-12-05 09:22:20 -05:00
parent d37413a400
commit a15c89d769
4 changed files with 225 additions and 93 deletions

View File

@@ -2,6 +2,7 @@ package elements
import (
"fluids/fluid"
"fluids/gamedata"
"image/color"
"github.com/hajimehoshi/ebiten/v2"
@@ -9,24 +10,29 @@ import (
)
const (
FS10PixelWidth = 200
FS10PixelWidth = 100
FS10PixelHeight = 100
FS10FluidWidth = 3.0 //meters
FS10FluidWidth = 1.0 //meters
FS10FluidHeight = 1.0 //meters
FS10Resolution = 20 //need to workshop this
)
type FluidSim10 struct {
MappedEntityBase
fluid *fluid.Fluid
angle float64
particlebuff *ebiten.Image
fluid *fluid.Fluid
angle float64
particlebuff *ebiten.Image
renderparticles bool
renderfield bool
fieldscale gamedata.Vector
}
func NewFluidSim10() *FluidSim10 {
fsim := &FluidSim10{
fluid: fluid.NewFluid(fluid.FieldVector{X: FS10FluidWidth, Y: FS10FluidHeight}, FS10FluidHeight/FS10Resolution),
particlebuff: ebiten.NewImage(1, 1),
fluid: fluid.NewFluid(fluid.FieldVector{X: FS10FluidWidth, Y: FS10FluidHeight}, FS10FluidHeight/FS10Resolution),
particlebuff: ebiten.NewImage(1, 1),
renderfield: true, //false,
renderparticles: false, //true,
}
fsim.Initialize()
return fsim
@@ -36,6 +42,12 @@ func (f *FluidSim10) Initialize() {
f.Sprite = ebiten.NewImage(FS10PixelWidth, FS10PixelHeight)
f.particlebuff.Fill(color.White)
f.fluid.Initialize()
//fieldscale for rendering purposes
f.fieldscale = gamedata.Vector{
X: FS10PixelWidth / float64(f.fluid.Field.Nx-1),
Y: FS10PixelHeight / float64(f.fluid.Field.Ny-1),
}
}
func (f *FluidSim10) SetAngle(angle float64) {
@@ -50,20 +62,61 @@ func (f *FluidSim10) GetAngle() float64 {
func (f *FluidSim10) Draw() {
f.Sprite.Clear()
vector.StrokeRect(f.Sprite, 0, 0, FS10PixelWidth, FS10PixelHeight, 2, color.White, true)
if f.renderfield {
/*
alternatively, single loop (not nested) with x/y cell coordinates given by
xi := i % f.fluid.Field.Ny
yi := i / f.fluid.Field.Ny
*/
for i := range f.fluid.Field.Nx {
for j := range f.fluid.Field.Ny {
for i := range f.fluid.Particles {
//for each particle, compute its relative position based on its
//position within the fluid field
p := &f.fluid.Particles[i]
percentx := p.Position.X / f.fluid.Field.Dimensions.X
percenty := p.Position.Y / f.fluid.Field.Dimensions.Y
ox := float64(percentx * FS10PixelWidth)
oy := float64(percenty * FS10PixelHeight)
idx := i*f.fluid.Field.Ny + j
op := &ebiten.DrawImageOptions{}
op.GeoM.Translate(ox, oy)
f.Sprite.DrawImage(f.particlebuff, op)
if f.fluid.Field.CellType[idx] != fluid.CellTypeFluid {
continue
}
celldensity := f.fluid.ParticleDensity[idx] / f.fluid.ParticleRestDensity
if celldensity > 0.8 {
celldensity = 1
}
ox := float64(i) * f.fieldscale.X
oy := float64(j) * f.fieldscale.Y
op := &ebiten.DrawImageOptions{}
op.GeoM.Translate(-.5, -.5)
op.GeoM.Scale(f.fieldscale.X, f.fieldscale.Y)
op.GeoM.Translate(ox, oy)
op.ColorScale.ScaleAlpha(celldensity)
op.ColorM.Scale(0, 0, 1, 1)
f.Sprite.DrawImage(f.particlebuff, op)
}
}
}
if f.renderparticles {
for i := range f.fluid.Particles {
//for each particle, compute its relative position based on its
//position within the fluid field
p := &f.fluid.Particles[i]
percentx := (p.Position.X - f.fluid.Field.H/2) / f.fluid.Field.Dimensions.X
percenty := (p.Position.Y - f.fluid.Field.H/2) / f.fluid.Field.Dimensions.Y
ox := float64(percentx * FS10PixelWidth)
oy := float64(percenty * FS10PixelHeight)
op := &ebiten.DrawImageOptions{}
op.GeoM.Translate(ox, oy)
f.Sprite.DrawImage(f.particlebuff, op)
}
}
if f.fluid.Block {
vector.StrokeRect(f.Sprite, 0, 0, FS10PixelWidth, FS10PixelHeight, 2, color.White, true)
} else {
radius := float32(f.fluid.Field.Nx) * f.fluid.Field.H / 2
pixelradius := radius/f.fluid.Field.Dimensions.X*FS10PixelWidth - 4
vector.StrokeCircle(f.Sprite, FS10PixelWidth/2, FS10PixelHeight/2, pixelradius, 2, color.White, true)
}
}
@@ -75,3 +128,19 @@ func (f *FluidSim10) Update() {
f.fluid.Step()
}
func (f *FluidSim10) EnableParticleRender(v bool) {
f.renderparticles = v
}
func (f *FluidSim10) EnableFieldRender(v bool) {
f.renderfield = v
}
func (f *FluidSim10) ToggleShape() {
f.fluid.ToggleShape()
}
func (f *FluidSim10) ToggleParticles() {
f.renderparticles = !f.renderparticles
}