Skip to content

Commit

Permalink
move dual contour stuff around
Browse files Browse the repository at this point in the history
  • Loading branch information
soypat committed Oct 21, 2024
1 parent 8cc883d commit f881cdd
Show file tree
Hide file tree
Showing 4 changed files with 24 additions and 66 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# Go workspaces.
go.work
go.work.sum
!examples/_dualcontour/go.work
# Test binary, built with `go test -c`
*.test
# Dependency directories after running `go mod vendor`
Expand Down
22 changes: 5 additions & 17 deletions glrender/dual_contour.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,6 @@ import (
"github.com/soypat/gsdf/gleval"
)

type DualContourer interface {
// PlaceVertices should edit the FinalVertex field of all [DualCube]s in the cubes buffer.
// These resulting vertices are then used for quad/triangle meshing.
PlaceVertices(cubes []DualCube, origin ms3.Vec, res float32, sdf gleval.SDF3, posbuf []ms3.Vec, distbuf []float32, userData any) error
}

type DualContourRenderer struct {
sdf gleval.SDF3
contourer DualContourer
Expand Down Expand Up @@ -201,6 +195,7 @@ func makeDualCube(ivec ivec, data []float32) DualCube {

// DualCube corresponds to a voxel anmd contains both cube and edge data.
type DualCube struct {
// ivec stores the octree index of the cube, used to find neighboring cube ivec indices and the absolute position of the cube.
ivec ivec
// Neighbors contains neighboring index into dualCube buffer and contributing edge intersect axis.
// - Neighbors[0]: Index into dualCube buffer to cube neighbor with edge.
Expand All @@ -209,22 +204,15 @@ type DualCube struct {
Neighbors [][3]int
// Distance from cube origin to SDF.
OrigDist float32
// Distance from (x,y,z) edge vertices to SDF.
// Distance from (x,y,z) edge vertices to SDF. These edges are coincident with cube origin.
XDist, YDist, ZDist float32
// FinalVertex set by vertex strategy. Decides the final resting place of the vertex of the cube
// FinalVertex set by vertex placement strategy. Decides the final resting place of the vertex of the cube
// which will be the vertex meshed.
FinalVertex ms3.Vec
}

func vertMean(verts []ms3.Vec) (mean ms3.Vec) {
for i := 0; i < len(verts); i++ {
mean = ms3.Add(mean, verts[i])
}
return ms3.Scale(1./float32(len(verts)), mean)
}

func (dc *DualCube) SizeAndOrigin(res float32, modelOrigin ms3.Vec) (float32, ms3.Vec) {
return res, icube{ivec: dc.ivec, lvl: 1}.origin(modelOrigin, res)
func (dc *DualCube) SizeAndOrigin(res float32, octreeOrigin ms3.Vec) (float32, ms3.Vec) {
return res, icube{ivec: dc.ivec, lvl: 1}.origin(octreeOrigin, res)
}

func (dc *DualCube) IsActive() bool {
Expand Down
22 changes: 17 additions & 5 deletions glrender/dual_contour_vertexplacement.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,18 @@ import (
"github.com/soypat/gsdf/gleval"
)

// DualContourLeastSquaresLocal is a vertex placement strategy which solves the least squares problem
// to place vertices locally.
type DualContourLeastSquaresLocal struct {
type DualContourer interface {
// PlaceVertices should edit the FinalVertex field of all [DualCube]s in the cubes buffer.
// These resulting vertices are then used for quad/triangle meshing.
PlaceVertices(cubes []DualCube, origin ms3.Vec, res float32, sdf gleval.SDF3, posbuf []ms3.Vec, distbuf []float32, userData any) error
}

func (lsq *DualContourLeastSquaresLocal) PlaceVertices(cubes []DualCube, origin ms3.Vec, res float32, sdf gleval.SDF3, posbuf []ms3.Vec, distbuf []float32, userData any) error {
// DualContourLeastSquares is a vertex placement strategy which solves the least squares problem
// to place vertices.
type DualContourLeastSquares struct {
}

func (lsq *DualContourLeastSquares) PlaceVertices(cubes []DualCube, origin ms3.Vec, res float32, sdf gleval.SDF3, posbuf []ms3.Vec, distbuf []float32, userData any) error {
// Prepare for normal calculation.
posbuf = posbuf[:0]
for c := range cubes {
Expand Down Expand Up @@ -83,7 +89,6 @@ func (lsq *DualContourLeastSquaresLocal) PlaceVertices(cubes []DualCube, origin
if math32.Abs(det) < 1e-5 {
// Singular or near-singular matrix; fall back to mean position
cubes[e].FinalVertex = bias
// dc.vert = vert
} else {
// U, S, _ := AtA.SVD()
// diag := S.VecDiag()
Expand All @@ -99,3 +104,10 @@ func (lsq *DualContourLeastSquaresLocal) PlaceVertices(cubes []DualCube, origin
}
return nil
}

func vertMean(verts []ms3.Vec) (mean ms3.Vec) {
for i := 0; i < len(verts); i++ {
mean = ms3.Add(mean, verts[i])
}
return ms3.Scale(1./float32(len(verts)), mean)
}
45 changes: 1 addition & 44 deletions glrender/glrender_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ func TestDualRender(t *testing.T) {
}
var dcr DualContourRenderer
var vp gleval.VecPool
err = dcr.Reset(sdf, res, &DualContourLeastSquaresLocal{}, &vp)
err = dcr.Reset(sdf, res, &DualContourLeastSquares{}, &vp)
if err != nil {
t.Fatal(err)
}
Expand Down Expand Up @@ -77,49 +77,6 @@ func TestMinecraftRender(t *testing.T) {
}
}

type cubeLowEdges struct {
active uint8 // bitfield marks active. 0:x, 1:y, 2:z
}

func contour(s gleval.SDF3, cubes []icube, origin ms3.Vec, res float32, posbuf []ms3.Vec, distbuf []float32, userData any) error {
iCubes := 0
for ; iCubes < len(cubes) && iCubes*4 < len(posbuf); iCubes++ {
cube := cubes[iCubes]
cubeCenter := cube.center(origin, res)
size := cube.size(res)

posbuf[iCubes*4] = cubeCenter
posbuf[iCubes*4+1] = ms3.Add(cubeCenter, ms3.Vec{X: size})
posbuf[iCubes*4+2] = ms3.Add(cubeCenter, ms3.Vec{Y: size})
posbuf[iCubes*4+3] = ms3.Add(cubeCenter, ms3.Vec{Z: size})
}

nPos := iCubes * 4
err := s.Evaluate(posbuf[:nPos], distbuf[:nPos], userData)
if err != nil {
return err
}

for j := 0; j < iCubes; j++ {
c := distbuf[j*4]
x := distbuf[j*4+1]
y := distbuf[j*4+2]
z := distbuf[j*4+3]
cbit := math32.Signbit(c)
if cbit != math32.Signbit(x) {

}
if cbit != math32.Signbit(y) {

}
if cbit != math32.Signbit(z) {

}
}

return nil
}

func TestSphereMarchingTriangles(t *testing.T) {
const r = 1.0
const bufsize = 1 << 12
Expand Down

0 comments on commit f881cdd

Please sign in to comment.