js/SceneKit/SCNTorus.js
- 'use strict'
-
- import SCNGeometry from './SCNGeometry'
- import SCNGeometryElement from './SCNGeometryElement'
- import SCNGeometryPrimitiveType from './SCNGeometryPrimitiveType'
- import SCNGeometrySource from './SCNGeometrySource'
- import SCNMaterial from './SCNMaterial'
- import SCNVector3 from './SCNVector3'
-
- /**
- * A torus, or ring-shaped geometry.
- * @access public
- * @extends {SCNGeometry}
- * @see https://developer.apple.com/documentation/scenekit/scntorus
- */
- export default class SCNTorus extends SCNGeometry {
- // Creating a Torus
-
- /**
- * Creates a torus geometry with the specified ring radius and pipe radius.
- * @access public
- * @constructor
- * @param {number} ringRadius - The major radius of the torus, defining its circular ring in the x- and z-axis dimensions of its local coordinate space.
- * @param {number} pipeRadius - The minor radius of the torus, defining the pipe that encircles the ring.
- * @desc The torus is centered in its local coordinate system. For example, if you create a torus whose ring radius is 5.0 and pipe radius is 1.0, it extends from -6.0 to 6.0 (with a hole through the center from -4.0 to 4.0) in the x- and z-axes and from -1.0 to 1.0 in the y-axis.
- * @see https://developer.apple.com/documentation/scenekit/scntorus/1523833-init
- */
- constructor(ringRadius = 0.5, pipeRadius = 0.25) {
- super([], [])
-
- // Adjusting a Torus’ Dimensions
-
- /**
- * The major radius of the torus, defining a circle in the x- and z-axis dimensions. Animatable.
- * @type {number}
- * @see https://developer.apple.com/documentation/scenekit/scntorus/1522906-ringradius
- */
- this.ringRadius = ringRadius
-
- /**
- * The minor radius of the torus, defining the pipe that encircles the torus ring. Animatable.
- * @type {number}
- * @see https://developer.apple.com/documentation/scenekit/scntorus/1522623-piperadius
- */
- this.pipeRadius = pipeRadius
-
-
- // Configuring Torus Properties
-
- /**
- * The number of subdivisions around the torus ring. Animatable.
- * @type {number}
- * @see https://developer.apple.com/documentation/scenekit/scntorus/1523598-ringsegmentcount
- */
- this.ringSegmentCount = 48
-
- /**
- * The number of subdivisions around the torus pipe. Animatable.
- * @type {number}
- * @see https://developer.apple.com/documentation/scenekit/scntorus/1522807-pipesegmentcount
- */
- this.pipeSegmentCount = 24
-
- this._createGeometry()
- this.materials.push(new SCNMaterial())
- }
-
- _createGeometry() {
- const sourceData = []
- const indexData = []
- const vectorCount = (this.ringSegmentCount + 1) * (this.pipeSegmentCount + 1)
-
- for(let ri=0; ri<=this.ringSegmentCount; ri++){
- const r = 2.0 * ri * Math.PI / this.ringSegmentCount
- const sinr = Math.sin(r)
- const cosr = Math.cos(r)
- const cx = -sinr * this.ringRadius
- const cz = -cosr * this.ringRadius
- const tx = ri / this.ringSegmentCount
-
- for(let pi=0; pi<=this.pipeSegmentCount; pi++){
- const pr = 2.0 * pi * Math.PI / this.pipeSegmentCount
- const sinp = Math.sin(pr)
- const cosp = Math.cos(pr)
- const x = cx + this.pipeRadius * sinr * cosp
- const y = -this.pipeRadius * sinp
- const z = cz + this.pipeRadius * cosr * cosp
-
- // vertex
- sourceData.push(x, y, z)
-
- // normal
- sourceData.push(sinr * cosp, -sinp, cosr * cosp)
-
- // texcoord
- const tz = 1.0 - pi / this.pipeSegmentCount
- sourceData.push(tx, tz)
- }
- }
-
- const vertexSource = new SCNGeometrySource(
- sourceData, // data
- SCNGeometrySource.Semantic.vertex, // semantic
- vectorCount, // vectorCount
- true, // floatComponents
- 3, // componentsPerVector
- 4, // bytesPerComponent
- 0, // offset
- 32 // sride
- )
-
- const normalSource = new SCNGeometrySource(
- sourceData, // data
- SCNGeometrySource.Semantic.normal, // semantic
- vectorCount, // vectorCount
- true, // floatComponents
- 3, // componentsPerVector
- 4, // bytesPerComponent
- 12, // offset
- 32 // stride
- )
-
- const texcoordSource = new SCNGeometrySource(
- sourceData, // data
- SCNGeometrySource.Semantic.texcoord, // semantic
- vectorCount, // vectorCount
- true, // floatComponents
- 2, // componentsPerVector
- 4, // bytesPerComponent
- 24, // offset
- 32 // stride
- )
-
- const indexLen = this.ringSegmentCount * this.pipeSegmentCount
- let base = 0
- for(let i=0; i<indexLen; i++){
- const i2 = base + this.pipeSegmentCount + 1
- indexData.push(base, i2+1, base+1)
- indexData.push(base, i2, i2+1)
- base += 1
- if((i+1) % this.pipeSegmentCount === 0){
- base += 1
- }
- }
-
- const element = new SCNGeometryElement(indexData, SCNGeometryPrimitiveType.triangles)
-
- this._geometryElements = [element]
- this._geometrySources = [vertexSource, normalSource, texcoordSource]
- this.boundingBox = {
- min: new SCNVector3(-this.radius, -this.radius, -this.radius),
- max: new SCNVector3(this.radius, this.radius, this.radius)
- }
- }
- }