github.com/Yeicor/sdf-viewer-go/sdf-viewer-go@v0.0.0-20220827152733-64b36e48c502/example/main.go (about)

     1  package main
     2  
     3  import (
     4  	"fmt"
     5  	sdfviewergo "github.com/Yeicor/sdf-viewer-go/sdf-viewer-go"
     6  	"math"
     7  )
     8  
     9  //export init
    10  func init() {
    11  	// This is the only function you need to call to initialize the SDF Viewer.
    12  	sdfviewergo.SetRootSDF(sceneSDF())
    13  }
    14  
    15  func main() {
    16  	fmt.Println("This is not an executable. Compile this with `" +
    17  		"tinygo build -o example.wasm -target wasi -opt 2 -x -no-debug ." +
    18  		"` and use the SDF Viewer app (github.com/Yeicor/sdf-viewer) to visualize the SDF.")
    19  }
    20  
    21  // sceneSDF returns the root SDF of the scene.
    22  func sceneSDF() sdfviewergo.SDF {
    23  	return &SampleSDF{isRoot: true, name: "test-root-cube", cubeHalfSide: 0.99, changed: false,
    24  		child: &SampleSDF{isRoot: false, name: "test-fake-child", cubeHalfSide: 0.51, changed: false}}
    25  }
    26  
    27  // ######################## START OF EXAMPLE MANUAL SDF IMPLEMENTATION ########################
    28  // NOTE: Other modules of this repo have better examples of how to implement SDFs.
    29  
    30  type SampleSDF struct {
    31  	isRoot       bool
    32  	child        *SampleSDF // May be nil
    33  	name         string
    34  	cubeHalfSide float32 // Cube side length
    35  	changed      bool    // Whether any param changed, affecting the whole SDF
    36  }
    37  
    38  func (s *SampleSDF) AABB() [2][3]float32 {
    39  	return [2][3]float32{{-1, -1, -1}, {1, 1, 1}}
    40  }
    41  
    42  func (s *SampleSDF) Sample(point [3]float32, distanceOnly bool) (sample sdfviewergo.SDFSample) {
    43  	// Cube SDF
    44  	sample.Distance = maxF32(maxF32(absF32(point[0]), absF32(point[1])), absF32(point[2])) - s.cubeHalfSide
    45  	if !distanceOnly {
    46  		sample.Color = [3]float32{sinF32(point[0] * 2.0), (point[1] + 1.0) / 2.0, (point[2] + 1.0) / 2.0}
    47  		sample.Metallic = modF32(point[0], 1.0)
    48  		sample.Roughness = modF32(point[1], 1.0)
    49  		sample.Occlusion = modF32(point[2], 1.0)
    50  	}
    51  	return
    52  }
    53  
    54  func (s *SampleSDF) Children() []sdfviewergo.SDF {
    55  	if s.child != nil { // Fake, just for testing...
    56  		return []sdfviewergo.SDF{s.child}
    57  	}
    58  	return []sdfviewergo.SDF{}
    59  }
    60  
    61  func (s *SampleSDF) Name() string {
    62  	return s.name
    63  }
    64  
    65  func (s *SampleSDF) Parameters() []sdfviewergo.SDFParam {
    66  	if !s.isRoot {
    67  		return []sdfviewergo.SDFParam{}
    68  	}
    69  	return []sdfviewergo.SDFParam{
    70  		{
    71  			ID:   0,
    72  			Name: "Cube half side",
    73  			Kind: sdfviewergo.SDFParamKindFloat{
    74  				Min:  0.01,
    75  				Max:  0.99,
    76  				Step: 0.01,
    77  			},
    78  			Value:       s.cubeHalfSide, // float32, as described
    79  			Description: "Half side length of the cube",
    80  		},
    81  	}
    82  }
    83  
    84  func (s *SampleSDF) SetParameter(paramId uint32, value sdfviewergo.SDFParamValue) error {
    85  	if paramId == 0 {
    86  		s.cubeHalfSide = value.(float32)
    87  		s.changed = true
    88  		return nil
    89  	}
    90  	return fmt.Errorf("unknown parameter id: %d", paramId)
    91  }
    92  
    93  func (s *SampleSDF) Changed() sdfviewergo.ChangedAABB {
    94  	changed := s.changed
    95  	s.changed = false
    96  	return sdfviewergo.ChangedAABB{
    97  		Changed: changed,
    98  		AABB:    s.AABB(),
    99  	}
   100  }
   101  
   102  // ######################## END OF EXAMPLE MANUAL SDF IMPLEMENTATION ########################
   103  
   104  func sinF32(f float32) float32 {
   105  	return float32(math.Sin(float64(f)))
   106  }
   107  
   108  func modF32(f float32, f2 float32) float32 {
   109  	res := float32(math.Mod(float64(f), float64(f2)))
   110  	if res < 0 {
   111  		return res + f2
   112  	}
   113  	return res
   114  }
   115  
   116  func maxF32(v1 float32, v2 float32) float32 {
   117  	if v1 > v2 {
   118  		return v1
   119  	}
   120  	return v2
   121  }
   122  
   123  func absF32(v float32) float32 {
   124  	if v < 0 {
   125  		return -v
   126  	}
   127  	return v
   128  }