Home Reference Source Repository

js/SceneKit/SCNPlane.js

  1. 'use strict'
  2.  
  3. import SCNGeometry from './SCNGeometry'
  4. import SCNGeometrySource from './SCNGeometrySource'
  5. import SCNGeometryElement from './SCNGeometryElement'
  6. import SCNGeometryPrimitiveType from './SCNGeometryPrimitiveType'
  7. import SCNMaterial from './SCNMaterial'
  8. import SCNVector3 from './SCNVector3'
  9.  
  10. /**
  11. * A rectangular, one-sided plane geometry of specified width and height.
  12. * @access public
  13. * @extends {SCNGeometry}
  14. * @see https://developer.apple.com/documentation/scenekit/scnplane
  15. */
  16. export default class SCNPlane extends SCNGeometry {
  17. static get _propTypes() {
  18. return {
  19. width: 'float',
  20. height: 'float',
  21. widthSegmentCount: 'integer',
  22. heightSegmentCount: 'integer',
  23. cornerRadius: 'float',
  24. cornerSegmentCount: 'integer',
  25. materials: 'NSArray',
  26. tessellator: 'SCNGeometryTessellator',
  27. wantsAdaptiveSubdivision: 'boolean',
  28.  
  29. name: 'string',
  30. primitiveType: ['integer', null],
  31. subdivisionLevel: 'integer',
  32. subdivisionSettings: ['bytes', null]
  33. }
  34. }
  35.  
  36. // Creating a Plane
  37.  
  38. /**
  39. * Creates a plane geometry with the specified width and height.
  40. * @access public
  41. * @constructor
  42. * @param {number} width - The width of the plane along the x-axis of its local coordinate space.
  43. * @param {number} height - The height of the plane along the y-axis of its local coordinate space.
  44. * @desc The plane is centered in its local coordinate system. For example, if you create a plane whose width and height are both 10.0, it extends from -5.0 to 5.0 along both the x- and y-axes, and the z-coordinate of all points in the plane is zero.
  45. * @see https://developer.apple.com/documentation/scenekit/scnplane/1523631-init
  46. */
  47. constructor(width = 1.0, height = 1.0) {
  48. super([], [])
  49.  
  50. // Adjusting a Plane’s Dimensions
  51.  
  52. /**
  53. * The extent of the plane along its horizontal axis. Animatable.
  54. * @type {number}
  55. * @see https://developer.apple.com/documentation/scenekit/scnplane/1523782-width
  56. */
  57. this.width = width
  58.  
  59. /**
  60. * The extent of the plane along its vertical axis. Animatable.
  61. * @type {number}
  62. * @see https://developer.apple.com/documentation/scenekit/scnplane/1522837-height
  63. */
  64. this.height = height
  65.  
  66.  
  67. // Adjusting Geometric Detail
  68.  
  69. /**
  70. * The number of subdivisions in the plane’s surface along its horizontal axis. Animatable.
  71. * @type {number}
  72. * @see https://developer.apple.com/documentation/scenekit/scnplane/1523991-widthsegmentcount
  73. */
  74. this.widthSegmentCount = 1
  75.  
  76. /**
  77. * The number of subdivisions in the plane’s surface along its vertical axis. Animatable.
  78. * @type {number}
  79. * @see https://developer.apple.com/documentation/scenekit/scnplane/1522889-heightsegmentcount
  80. */
  81. this.heightSegmentCount = 1
  82.  
  83.  
  84. // Adding Rounded Corners
  85.  
  86. /**
  87. * The radius of curvature for the plane’s corners. Animatable.
  88. * @type {number}
  89. * @see https://developer.apple.com/documentation/scenekit/scnplane/1523005-cornerradius
  90. */
  91. this.cornerRadius = 0
  92.  
  93. /**
  94. * The number of line segments used to create each rounded corner of the plane. Animatable.
  95. * @type {number}
  96. * @see https://developer.apple.com/documentation/scenekit/scnplane/1524234-cornersegmentcount
  97. */
  98. this.cornerSegmentCount = 10
  99.  
  100. this._createGeometry()
  101. this.materials.push(new SCNMaterial())
  102. }
  103.  
  104. _createGeometry() {
  105. const sourceData = []
  106. const indexData = []
  107.  
  108. // TODO: chamfer
  109. const wStep = 1.0 / this.widthSegmentCount
  110. for(let i=0; i<=this.heightSegmentCount; i++){
  111. const ty = i / this.heightSegmentCount
  112. const y = (-0.5 + ty) * this.height
  113. for(let j=0; j<=this.widthSegmentCount; j++){
  114. const tx = j / this.widthSegmentCount
  115. const x = (-0.5 + tx) * this.width
  116.  
  117. sourceData.push(x, y, 0.0) // position
  118. sourceData.push(0.0, 0.0, 1.0) // normal
  119. sourceData.push(tx, 1.0 - ty) // texcoord
  120. }
  121. }
  122.  
  123. const numSegments = this.widthSegmentCount * this.heightSegmentCount
  124. for(let i=0; i<numSegments; i++){
  125. const index = i * 4
  126. indexData.push(index, index + 1, index + 3)
  127. indexData.push(index, index + 3, index + 2)
  128. }
  129.  
  130. const vectorCount = (this.widthSegmentCount + 1) * (this.heightSegmentCount + 1)
  131.  
  132. const vertexSource = new SCNGeometrySource(
  133. sourceData, // data
  134. SCNGeometrySource.Semantic.vertex, // semantic
  135. vectorCount, // vectorCount
  136. true, // floatComponents
  137. 3, // componentsPerVector
  138. 4, // bytesPerComponent
  139. 0, // offset
  140. 32 // sride
  141. )
  142.  
  143. const normalSource = new SCNGeometrySource(
  144. sourceData, // data
  145. SCNGeometrySource.Semantic.normal, // semantic
  146. vectorCount, // vectorCount
  147. true, // floatComponents
  148. 3, // componentsPerVector
  149. 4, // bytesPerComponent
  150. 12, // offset
  151. 32 // stride
  152. )
  153.  
  154. const texcoordSource = new SCNGeometrySource(
  155. sourceData, // data
  156. SCNGeometrySource.Semantic.texcoord, // semantic
  157. vectorCount, // vectorCount
  158. true, // floatComponents
  159. 2, // componentsPerVector
  160. 4, // bytesPerComponent
  161. 24, // offset
  162. 32 // stride
  163. )
  164.  
  165. const element = new SCNGeometryElement(indexData, SCNGeometryPrimitiveType.triangles)
  166.  
  167. this._geometryElements = [element]
  168. this._geometrySources = [vertexSource, normalSource, texcoordSource]
  169. this.boundingBox = {
  170. min: new SCNVector3(-0.5 * this.width, -0.5 * this.height, 0.0),
  171. max: new SCNVector3(0.5 * this.width, 0.5 * this.height, 0.0)
  172. }
  173. }
  174. }