github.com/EngineerKamesh/gofullstack@v0.0.0-20180609171605-d41341d7d4ee/volume3/section2/3dgopher/3dgopherfinal/3dgopherfinal.go (about) 1 package main 2 3 import ( 4 "math" 5 6 "github.com/gopherjs/gopherjs/js" 7 "github.com/gopherjs/jsbuiltin" 8 "honnef.co/go/js/dom" 9 ) 10 11 var JS = js.Global 12 var D = dom.GetWindow().Document() 13 14 var container *dom.HTMLDivElement 15 var camera *js.Object 16 var cameraTarget *js.Object 17 var scene *js.Object 18 var renderer *js.Object 19 var gopher *js.Object 20 21 type MeshPhongMaterialData struct { 22 *js.Object 23 Color int `js:"color"` 24 Specular int `js:"specular"` 25 Shininess int `js:"shininess"` 26 } 27 28 func main() { 29 println("Hello 3D Gopher!") 30 31 dom.GetWindow().AddEventListener("resize", false, func(event dom.Event) { 32 handleWindowResize() 33 }) 34 35 initialize() 36 animate() 37 } 38 39 func initialize() { 40 41 container = D.CreateElement("div").(*dom.HTMLDivElement) 42 D.QuerySelector("body").AppendChild(container) 43 44 camera = JS.Get("THREE").Get("PerspectiveCamera").New(39, JS.Get("window").Get("innerWidth").Int()/JS.Get("window").Get("innerHeight").Int(), 1, 15) 45 camera.Get("position").Call("set", 6, 0.54, 6) 46 cameraTarget = JS.Get("THREE").Get("Vector3").New(0, 0, 0) 47 scene = JS.Get("THREE").Get("Scene").New() 48 49 fog := JS.Get("THREE").Get("Fog").New(0x708090, 2, 15) 50 scene.Set("fog", fog) 51 52 planeMeshData := &MeshPhongMaterialData{Object: js.Global.Get("Object").New()} 53 planeMeshData.Color = 0xA9A9A9 54 planeMeshData.Specular = 0x000000 55 56 planeMeshPhongMaterial := JS.Get("THREE").Get("MeshPhongMaterial").New(planeMeshData) 57 planeBufferGeometry := JS.Get("THREE").Get("PlaneBufferGeometry").New(40, 40) 58 plane := JS.Get("THREE").Get("Mesh").New(planeBufferGeometry, planeMeshPhongMaterial) 59 60 plane.Get("rotation").Set("x", -1*(math.Pi/2)) 61 plane.Get("position").Set("y", -0.5) 62 63 scene.Call("add", plane) 64 65 loader := JS.Get("THREE").Get("OBJLoader").New() 66 loader.Call("load", "/obj/gogopher.obj", func(mesh *js.Object) { 67 68 gopherMeshPhongMaterial := &MeshPhongMaterialData{Object: js.Global.Get("Object").New()} 69 gopherMeshPhongMaterial.Color = 0x007794 70 gopherMeshPhongMaterial.Specular = 0x111111 71 gopherMeshPhongMaterial.Shininess = 200 72 73 material := JS.Get("THREE").Get("MeshPhongMaterial").New(gopherMeshPhongMaterial) 74 mesh.Call("traverse", func(child *js.Object) { 75 if jsbuiltin.InstanceOf(child, JS.Get("THREE").Get("Mesh")) { 76 child.Set("material", material) 77 println(material) 78 } 79 80 }) 81 82 mesh.Get("position").Call("set", 0.06, -0.45, 0.7) 83 mesh.Get("scale").Call("set", 0.004, 0.0054, 0.004) 84 mesh.Set("castsShadow", true) 85 mesh.Set("receiveShadow", true) 86 87 scene.Call("add", mesh) 88 89 }) 90 91 hemisphereLight := JS.Get("THREE").Get("HemisphereLight").New(0xf0f0f0, 0x000000) 92 scene.Call("add", hemisphereLight) 93 addDirectionalLight(-0.5, 3, -1.0, 0xf0f0f0, 1) 94 renderer = JS.Get("THREE").Get("WebGLRenderer").New() 95 renderer.Call("setClearColor", scene.Get("fog").Get("color")) 96 renderer.Call("setPixelRatio", JS.Get("window").Get("devicePixelRatio")) 97 renderer.Call("setSize", JS.Get("window").Get("innerWidth").Int(), JS.Get("window").Get("innerHeight").Int()) 98 renderer.Set("gammaInput", true) 99 renderer.Set("gammaOutput", true) 100 renderer.Get("shadowMap").Set("enabled", true) 101 renderer.Get("shadowMap").Set("renderReverseSided", false) 102 container.Underlying().Call("appendChild", renderer.Get("domElement")) 103 } 104 105 func animate() { 106 JS.Get("window").Call("requestAnimationFrame", animate) 107 render() 108 } 109 110 func render() { 111 JS.Get("window").Call("panCamera", camera, cameraTarget) 112 camera.Call("lookAt", cameraTarget) 113 renderer.Call("render", scene, camera) 114 } 115 116 func addDirectionalLight(x float64, y float64, z float64, color int, intensity int) { 117 directionalLight := JS.Get("THREE").Get("DirectionalLight").New(color, intensity) 118 directionalLight.Get("position").Call("set", x, y, z) 119 scene.Call("add", directionalLight) 120 directionalLight.Set("castShadow", true) 121 d := 1 122 directionalLight.Get("shadow").Get("camera").Set("left", -d) 123 directionalLight.Get("shadow").Get("camera").Set("right", d) 124 directionalLight.Get("shadow").Get("camera").Set("top", d) 125 directionalLight.Get("shadow").Get("camera").Set("bottom", -d) 126 directionalLight.Get("shadow").Get("camera").Set("near", 1) 127 directionalLight.Get("shadow").Get("camera").Set("far", 4) 128 directionalLight.Get("shadow").Get("mapSize").Set("width", 1024) 129 directionalLight.Get("shadow").Get("mapSize").Set("height", 1024) 130 directionalLight.Get("shadow").Set("bias", -0.005) 131 } 132 133 func handleWindowResize() { 134 camera.Set("aspect", JS.Get("window").Get("innerWidth").Int()/JS.Get("window").Get("innerHeight").Int()) 135 camera.Call("updateProjectionMatrix") 136 renderer.Call("setSize", JS.Get("window").Get("innerWidth").Int(), JS.Get("window").Get("innerHeight").Int()) 137 }