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  }