我试图用THREEJS lib编写一个简单的示例来渲染多维数据集。
package three
import org.scalajs.dom
import scala.scalajs.js
import scala.scalajs.js.Dynamic._
import scala.scalajs.js.annotation.JSName
object THREE extends js.Object
{
@JSName ("THREE.Scene")
class Scene extends js.Object
{
def add(obj: js.Object) = ???
}
@JSName ("THREE.Vector3")
class Vector3(var x:js.Number, var y:js.Number, var z:js.Number) extends js.Object
@JSName ("THREE.PerspectiveCamera")
class PerspectiveCamera(a:js.Number,b:js.Number,c:js.Number,d:js.Number) extends js.Object
{
var position:Vector3 = _
}
@JSName ("THREE.WebGLRenderer")
class WebGLRenderer(params:js.Dynamic) extends js.Object
{
def render(scene:js.Object, camera:js.Object) = ???
}
@JSName ("THREE.WebGLRenderer")
class SimpleWebGLRenderer() extends js.Object
{
def render(scene:js.Object, camera:js.Object) = ???
var domElement : js.Dynamic = _
}
@JSName ("THREE.BoxGeometry")
class BoxGeometry(a:js.Number,b:js.Number,c:js.Number) extends js.Object
@JSName ("THREE.MeshBasicMaterial")
class MeshBasicMaterial(params:js.Dynamic) extends js.Object
@JSName ("THREE.MeshBasicMaterial")
class SimpleMeshBasicMaterial() extends js.Object
@JSName ("THREE.Mesh")
class Mesh(geometry:js.Object, material:js.Object) extends js.Object
}
object ThreeExample
{
def render() =
{
val scene = new THREE.Scene()
val camera = new THREE.PerspectiveCamera(75, 1, 0.1, 1000);
val renderer = new THREE.WebGLRenderer(js.Dynamic.literal(
canvas = global.document.getElementById("ThreeCanvas")
));
val geometry = new THREE.BoxGeometry(1,1,1);
val material = new THREE.SimpleMeshBasicMaterial()
camera.position.z = 2;
val cube = new THREE.Mesh(geometry, material);
现在有趣的部分。如果我试着写
scene.add(cube);
renderer.render(scene, camera);
我得到了
ScalaJS.c.jl_ClassCastException {s $ 1:" [object Object]不是scala.runtime.Nothing $",e $ 1:null,stackTrace $ 1:null,stackdata:TypeError,构造函数:function的实例...}
错误。如果我试试
global._scene = scene
global._cube = cube
global._camera = camera
global._renderer = renderer
global._scene.add(global._cube)
global._renderer.render(global._scene, global._camera);
一切都正确呈现没有错误。 我的意思是,捕获的是什么? global._scene和scene或global._scene.add和scene.add之间有区别吗?
答案 0 :(得分:3)
详细说明我的评论:基本上没有区别。静态类型接口只是与动态类型接口一起使用的相同机制的类型化外观。但是,因为它是静态的,所以它会通过您调用的方法对返回的值添加检查。
在您的情况下,当调用renderer.render()
时,编译器会添加一个检查,指出此JavaScript方法返回的值实际上符合WebGLRenderer.render()
的静态结果类型。但是这个结果类型是什么?它是Nothing
!这是为什么?由于此方法的主体为???
,其类型为Nothing
,因此scalac会将方法的结果类型推断为Nothing
。然后检查失败,因为render
从JavaScript返回的值不是Nothing
类型(显然,因为没有值具有该类型),这会导致ClassCastException
。
您想要的显然不是Nothing
,而是Unit
。所以你要做的就是用: Unit
明确这个结果类型:
def render(scene:js.Object, camera:js.Object): Unit = ???
通常,总是明确指定外观类型中方法的结果类型,因为否则它们被推断为Nothing
,这不是您想要的。