Пример #1
0
func (g *Geometry) ComputeVertexNormals(areaWeighted bool) {
	vertices := make([]*math3d.Vector3, len(g.Vertices))
	for v, _ := range g.Vertices {
		vertices[v] = math3d.NewEmptyVector3()
	}

	if areaWeighted {
		// vertex normals weighted by triangle areas
		// http://www.iquilezles.org/www/articles/normals/normals.htm
		var vA, vB, vC *math3d.Vector3
		cb := math3d.NewEmptyVector3()
		ab := math3d.NewEmptyVector3()
		for _, face := range g.Faces {
			vA = g.Vertices[face.A]
			vB = g.Vertices[face.B]
			vC = g.Vertices[face.C]

			cb.SubVectors(vC, vB)
			ab.SubVectors(vA, vB)
			cb.Cross(ab)

			vertices[face.A].Add(cb)
			vertices[face.B].Add(cb)
			vertices[face.C].Add(cb)
		}
	} else {
		for _, face := range g.Faces {
			vertices[face.A].Add(face.Normal)
			vertices[face.B].Add(face.Normal)
			vertices[face.C].Add(face.Normal)
		}
	}

	for v, _ := range g.Vertices {
		vertices[v].Normalize()
	}

	for _, face := range g.Faces {
		vertexNormals := face.VertexNormals

		if len(vertexNormals) == 3 {
			vertexNormals[0].Copy(vertices[face.A])
			vertexNormals[1].Copy(vertices[face.B])
			vertexNormals[2].Copy(vertices[face.C])
		} else {
			vertexNormals[0] = vertices[face.A].Clone()
			vertexNormals[1] = vertices[face.B].Clone()
			vertexNormals[2] = vertices[face.C].Clone()
		}
	}
}
Пример #2
0
func (g *Geometry) ComputeFaceNormals() {
	cb := math3d.NewEmptyVector3()
	ab := math3d.NewEmptyVector3()
	for _, face := range g.Faces {
		var vA = g.Vertices[face.A]
		var vB = g.Vertices[face.B]
		var vC = g.Vertices[face.C]

		cb.SubVectors(vC, vB)
		ab.SubVectors(vA, vB)
		cb.Cross(ab)

		cb.Normalize()

		face.Normal.Copy(cb)
	}
}
Пример #3
0
func (o *Object3D) buildGetWorldQuaternion() func(*math.Vector3) *math.Quaternion {

	position := math.NewEmptyVector3()
	scale := math.NewEmptyVector3()

	return func(optionalTarget *math.Vector3) *math.Quaternion {

		var result = optionalTarget
		if result == nil {
			result = math.NewEmptyQuaternion()
		}

		o.UpdateMatrixWorld(true)

		o.MatrixWorld.Decompose(position, result, scale)

		return result
	}
}
Пример #4
0
func (o *Object3D) buildGetWorldScale() func(*math.Vector3) *math.Vector3 {

	var position = math.NewEmptyVector3()
	var quaternion = math.NewEmptyQuaternion()

	return func(optionalTarget *math.Vector3) *math.Vector3 {

		result := optionalTarget
		if result == nil {
			result = math.NewEmptyVector3()
		}

		o.UpdateMatrixWorld(true)

		o.MatrixWorld.Decompose(position, quaternion, result)

		return result
	}
}
Пример #5
0
func (o *Object3D) GetWorldPosition(optionalTarget *math.Vector3) *math.Vector3 {

	result := optionalTarget
	if result == nil {
		result = math.NewEmptyVector3()
	}

	o.UpdateMatrixWorld(true)

	return result.SetFromMatrixPosition(o.MatrixWorld)
}
Пример #6
0
func NewArraysFace3(a, b, c int, normals []*math.Vector3, colors []*math.Color, materialIndex int) *Face3 {
	return &Face3{
		A:             a,
		B:             b,
		C:             c,
		Normal:        math.NewEmptyVector3(),
		VertexNormals: normals,
		Color:         math.NewDefaultColor(),
		VertexColors:  colors,
		MaterialIndex: materialIndex,
	}
}
Пример #7
0
func NewObject3D() *Object3D {
	Object3DIdCount++
	object3d := Object3D{
		NewEventDispatcher(),
		Id:                     Object3DIdCount,
		Uuid:                   math.GenerateUUID(),
		Name:                   "",
		Type:                   "Object3D",
		Parent:                 nil,
		Channels:               NewChannels(),
		Children:               make([]Object3D, 0),
		Up:                     DefaultUp.Clone(),
		Position:               math.NewEmptyVector3(),
		Rotation:               math.NewEmptyEuler(),
		Quaternion:             math.NewEmptyQuaternion(),
		Scale:                  math.NewVector3(1.0, 1.0, 1.0),
		RotationAutoUpdate:     true,
		Matrix:                 math.NewMatrix4(),
		MatrixWorld:            math.NewMatrix4(),
		MatrixAutoUpdate:       DefaultMatrixAutoUpdate,
		MatrixWorldNeedsUpdate: false,
		Visible:                true,
		CastShadow:             false,
		ReceiveShadow:          false,
		FrustumCulled:          true,
		RenderOrder:            0,
		UserData:               make(map[string]string),
		ModelViewMatrix:        math.NewMatrix4(),
		NormalMatrix:           *math.NewMatrix3(),
		Geometry:               nil,
	}

	onRotationChange := func() {
		object3d.Quaternion.SetFromEuler(object3d.Rotation, false)
	}

	onQuaternionChange := func() {
		object3d.Rotation.SetFromQuaternion(object3d.Quaternion, nil, false)
	}

	object3d.Rotation.OnChange(onRotationChange)
	object3d.Quaternion.OnChange(onQuaternionChange)

	object3d.GetWorldQuaternion = object3d.buildGetWorldQuaternion()
	object3d.GetWorldRotation = object3d.buildGetWorldRotation()
	object3d.GetWorldScale() = object3d.buildGetWorldScale()
	object3d.GetWorldDirection = object3d.buildGetWorldDirection()
	object3d.LookAt = object3d.buildLookAt()

	return &object3d
}
Пример #8
0
func (c *Camera) GetWorldDirection(optionalTarget *math.Vector3) *math.Vector3 {

	var quaternion = math.NewEmptyQuaternion()

	var result = optionalTarget
	if result == nil {
		result = math.NewEmptyVector3()
	}

	c.GetWorldQuaternion(quaternion)

	return result.Set(0, 0, -1).ApplyQuaternion(quaternion)

}
Пример #9
0
func (o *Object3D) buildGetWorldDirection() func(*math.Vector3) *math.Vector3 {

	var quaternion = math.NewEmptyQuaternion()

	return func(optionalTarget *math.Vector3) *math.Vector3 {

		result := optionalTarget
		if result == nil {
			result = math.NewEmptyVector3()
		}

		o.GetWorldQuaternion(quaternion)

		return result.Set(0, 0, 1).ApplyQuaternion(quaternion)
	}
}
Пример #10
0
func NewDefaultFace3(a, b, c int) *Face3 {
	return NewFace3(a, b, c, math.NewEmptyVector3(), math.NewDefaultColor(), 0)
}
Пример #11
0
func NewBoxGeometry(width, height, depth float64, widthSegments, heightSegments, depthSegments int) *BoxGeometry {
	g := &BoxGeometry{
		core.NewGeometry(),
		Width:          width,
		Height:         height,
		Depth:          depth,
		WidthSegments:  widthSegments,
		HeightSegments: heightSegments,
		DepthSegments:  depthSegments,
	}
	g.Type = "BoxGeometry"

	g.Parameters = map[string]interface{}{
		"width":          width,
		"height":         height,
		"depth":          depth,
		"widthSegments":  widthSegments,
		"heightSegments": heightSegments,
		"depthSegments":  depthSegments,
	}

	scope := g

	width_half := width / 2
	height_half := height / 2
	depth_half := depth / 2

	buildPlane := func(u, v string, udir, vdir int, width, height, depth float64, materialIndex int) {

		// w, ix, iy,
		var w string
		gridX := scope.WidthSegments
		gridY := scope.HeightSegments
		width_half := width / 2
		height_half := height / 2
		offset := len(scope.Vertices)

		if (u == "x" && v == "y") || (u == "y" && v == "x") {
			w = "z"
		} else if (u == "x" && v == "z") || (u == "z" && v == "x") {
			w = "y"
			gridY = scope.DepthSegments
		} else if (u == "z" && v == "y") || (u == "y" && v == "z") {
			w = "x"
			gridX = scope.DepthSegments
		}

		gridX1 := gridX + 1
		gridY1 := gridY + 1
		segment_width := width / gridX
		segment_height := height / gridY
		normal := math3d.NewEmptyVector3()

		if depth > 0 {
			three.SetField(normal, w, 1)
		} else {
			three.SetField(normal, w, -1)
		}

		for iy := 0; iy < gridY1; iy++ {
			for ix := 0; ix < gridX1; ix++ {
				var vector = math3d.NewEmptyVector3()
				three.SetField(vector, u, (ix*segment_width-width_half)*udir)
				three.SetField(vector, v, (iy*segment_height-height_half)*vdir)
				three.SetField(vector, w, depth)
				scope.Vertices = append(scope.Vertices, vector)
			}
		}

		for iy := 0; iy < gridY; iy++ {
			for ix := 0; ix < gridX; ix++ {
				a := ix + gridX1*iy
				b := ix + gridX1*(iy+1)
				c := (ix + 1) + gridX1*(iy+1)
				d := (ix + 1) + gridX1*iy

				uva := math3d.NewVector2(ix/gridX, 1-iy/gridY)
				uvb := math3d.NewVector2(ix/gridX, 1-(iy+1)/gridY)
				uvc := math3d.NewVector2((ix+1)/gridX, 1-(iy+1)/gridY)
				uvd := math3d.NewVector2((ix+1)/gridX, 1-iy/gridY)

				face := core.NewDefaultFace3(a+offset, b+offset, d+offset)
				face.Normal.Copy(normal)
				face.VertexNormals = append(face.VertexNormals, normal.Clone(), normal.Clone(), normal.Clone())
				face.MaterialIndex = materialIndex

				scope.Faces = append(scope.Faces, face)
				scope.FaceVertexUvs[0] = append(scope.FaceVertexUvs[0], []*math3d.Vector2{uva, uvb, uvd})

				face = core.NewDefaultFace3(b+offset, c+offset, d+offset)
				face.Normal.Copy(normal)
				face.VertexNormals = append(face.VertexNormals, normal.Clone(), normal.Clone(), normal.Clone())
				face.MaterialIndex = materialIndex

				scope.Faces = append(scope.Faces, face)
				scope.FaceVertexUvs[0] = append(scope.FaceVertexUvs[0], []*math3d.Vector2{uvb.Clone(), uvc, uvd.Clone()})
			}
		}
	}

	buildPlane("z", "y", -1, -1, depth, height, width_half, 0)  // px
	buildPlane("z", "y", 1, -1, depth, height, -width_half, 1)  // nx
	buildPlane("x", "z", 1, 1, width, depth, height_half, 2)    // py
	buildPlane("x", "z", 1, -1, width, depth, -height_half, 3)  // ny
	buildPlane("x", "y", 1, -1, width, height, depth_half, 4)   // pz
	buildPlane("x", "y", -1, -1, width, height, -depth_half, 5) // nz

	g.MergeVertices()
	return g
}