github.com/Yeicor/sdf-viewer-go/sdf-viewer-go@v0.0.0-20220827152733-64b36e48c502/exports.go (about) 1 package sdf_viewer_go 2 3 import ( 4 "math" 5 "unsafe" 6 ) 7 8 // availableSDFs is the exported SDF hierarchy implementations. 9 var availableSDFs map[uint32]SDF 10 var nextSDFID uint32 11 12 func registerSDFAndChildren(s SDF) { 13 //fmt.Printf("registerSDFAndChildren(%d)\n", nextSDFID) 14 availableSDFs[nextSDFID] = s 15 nextSDFID++ 16 for _, child := range s.Children() { 17 registerSDFAndChildren(child) 18 } 19 } 20 21 func getSDFOrPanic(sdfID uint32) SDF { 22 if sdf, ok := availableSDFs[sdfID]; ok { 23 return sdf 24 } 25 panic("SDF not found") 26 } 27 28 //export bounding_box 29 //goland:noinspection GoSnakeCaseUsage 30 func bounding_box(sdfID uint32) *[2][3]float32 { 31 //fmt.Printf("-> AABB(%d)\n", sdfID) 32 minMax := getSDFOrPanic(sdfID).AABB() 33 //fmt.Printf("<- AABB(%d) <- (%v, %v)\n", sdfID, minMax[0], minMax[1]) 34 return &minMax 35 } 36 37 //export sample 38 func sample(sdfID uint32, point [3]float32, distanceOnly bool) *SDFSample { 39 //fmt.Printf("Sample(%d, %v, %v)\n", sdfID, point, distanceOnly) 40 sample := getSDFOrPanic(sdfID).Sample(point, distanceOnly) 41 //fmt.Printf("Sample(%d, %v, %v) <- (%v)\n", sdfID, point, distanceOnly, sample) 42 return &sample 43 } 44 45 //export children 46 func children(sdfID uint32) *pointerLength { 47 //fmt.Printf("-> Children(%d)\n", sdfID) 48 children := getSDFOrPanic(sdfID).Children() 49 if len(children) == 0 { 50 res := pointerLength{Pointer: 0, Length: 0} 51 return &res 52 } 53 childrenIDs := make([]uint32, len(children)) 54 for i, child := range children { 55 var childID uint32 56 var ok bool 57 for id, s := range availableSDFs { // Too slow? 58 if s == child { 59 childID = id 60 ok = true 61 break 62 } 63 } 64 if !ok { 65 // NOTE: Children may change after a parameter update (or at any point in time), 66 // so register them again (with new IDs) if not found 67 // WARNING: A new struct instance on every Children call would cause a memory leak 68 registerSDFAndChildren(child) 69 childID = nextSDFID - 1 70 } 71 childrenIDs[i] = childID 72 } 73 res := pointerLength{Pointer: uintptr(unsafe.Pointer(&(childrenIDs[0]))), Length: uint32(uintptr(len(childrenIDs)) * unsafe.Sizeof(childrenIDs[0]))} 74 //fmt.Printf("<- Children(%d) <- (%v, %v)\n", sdfID, children.Pointer, children.Length) 75 return &res 76 } 77 78 //export name 79 func name(sdfID uint32) *pointerLength { 80 //fmt.Printf("-> Children(%d)\n", sdfID) 81 res := stringToPointerLength(getSDFOrPanic(sdfID).Name()) 82 //fmt.Printf("<- Children(%d) <- (%v, %v)\n", sdfID, children.Pointer, children.Length) 83 return &res 84 } 85 86 func stringToPointerLength(str string) pointerLength { 87 name := []byte(str) 88 res := pointerLength{Pointer: uintptr(unsafe.Pointer(&(name[0]))), Length: uint32(uintptr(len(name)) * unsafe.Sizeof(name[0]))} 89 return res 90 } 91 92 //export parameters 93 func parameters(sdfID uint32) *pointerLength { 94 //fmt.Printf("-> Parameters(%d)\n", sdfID) 95 params := getSDFOrPanic(sdfID).Parameters() 96 if len(params) == 0 { 97 res := pointerLength{Pointer: 0, Length: 0} 98 return &res 99 } 100 paramsC := make([]sdfParamC, len(params)) 101 for i, param := range params { 102 paramsC[i] = sdfParamC{ 103 ID: param.ID, 104 Name: stringToPointerLength(param.Name), 105 KindParams: kindC(param.Kind), 106 Value: kindValue(param.Value), 107 Description: stringToPointerLength(param.Description), 108 } 109 } 110 res := pointerLength{Pointer: uintptr(unsafe.Pointer(&(paramsC[0]))), Length: uint32(uintptr(len(paramsC)) * unsafe.Sizeof(paramsC[0]))} 111 //fmt.Printf("<- Parameters(%d) <- (%v, %v)\n", sdfID, res.Pointer, res.Length) 112 return &res 113 } 114 115 //export set_parameter 116 //goland:noinspection GoSnakeCaseUsage 117 func set_parameter(sdfID, paramID, paramKindID, paramArg1, paramArg2 uint32) *setParameterRes { 118 //fmt.Printf("-> SetParameter(%d, %d, %d, %d, %d)\n", sdfID, paramID, paramKindID, paramArg1, paramArg2) 119 var paramVal SDFParamValue 120 switch paramKindID { 121 case 0: // bool 122 paramVal = paramArg1 != 0 123 case 1: // int 124 paramVal = *(*int32)(unsafe.Pointer(¶mArg1)) 125 case 2: // float 126 paramVal = math.Float32frombits(paramArg1) 127 case 3: // string 128 //goland:noinspection GoVetUnsafePointer 129 memPtr := unsafe.Pointer(uintptr(paramArg1)) 130 memLen := paramArg2 131 var bytes = unsafe.Slice((*byte)(memPtr), memLen) 132 paramVal = string(bytes) 133 default: 134 panic("Invalid paramKindID") 135 } 136 err := getSDFOrPanic(sdfID).SetParameter(paramID, paramVal) 137 res := setParameterRes{Error: 0, ErrorMsg: pointerLength{Pointer: 0, Length: 0}} 138 //err = errors.New("testing error on set_parameter") 139 if err != nil { 140 name := []byte(err.Error()) 141 res.Error = 1 142 res.ErrorMsg.Pointer = uintptr(unsafe.Pointer(&(name[0]))) 143 res.ErrorMsg.Length = uint32(uintptr(len(name)) * unsafe.Sizeof(name[0])) 144 } 145 //fmt.Printf("<- SetParameter(%d) <- (%v, %v)\n", sdfID, res.Pointer, res.Length) 146 return &res 147 } 148 149 //export changed 150 func changed(sdfID uint32) *ChangedAABB { 151 //fmt.Printf("-> Changed(%d)\n", sdfID) 152 changed := getSDFOrPanic(sdfID).Changed() 153 res := changedAABBC{ 154 Changed: 0, 155 AABB: changed.AABB, 156 } 157 if changed.Changed { 158 res.Changed = 1 159 } 160 //fmt.Printf("<- Changed(%d) <- (%v)\n", sdfID, Changed) 161 return &changed 162 }