index.ts 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206
  1. /* eslint-disable @typescript-eslint/ban-types */
  2. import type { DefineComponent, VNode, VNodeRef } from 'vue'
  3. import type * as THREE from 'three'
  4. import type { EventProps as PointerEventHandlerEventProps } from '../composables/usePointerEventHandler'
  5. // Based on React Three Fiber types by Pmndrs
  6. // https://github.com/pmndrs/react-three-fiber/blob/v9/packages/fiber/src/three-types.ts
  7. export type AttachFnType<O = any> = (parent: any, self: O) => () => void
  8. export type AttachType<O = any> = string | AttachFnType<O>
  9. export type ConstructorRepresentation = new (...args: any[]) => any
  10. export type NonFunctionKeys<P> = { [K in keyof P]-?: P[K] extends Function ? never : K }[keyof P]
  11. export type Overwrite<P, O> = Omit<P, NonFunctionKeys<O>> & O
  12. export type Properties<T> = Pick<T, NonFunctionKeys<T>>
  13. export type Mutable<P> = { [K in keyof P]: P[K] | Readonly<P[K]> }
  14. export type Args<T> = T extends ConstructorRepresentation ? ConstructorParameters<T> : any[]
  15. export interface TresCatalogue {
  16. [name: string]: ConstructorRepresentation
  17. }
  18. export type TresCamera = THREE.OrthographicCamera | THREE.PerspectiveCamera
  19. export interface InstanceProps<T = any, P = any> {
  20. args?: Args<P>
  21. object?: T
  22. visible?: boolean
  23. dispose?: null
  24. attach?: AttachType<T>
  25. }
  26. interface TresBaseObject {
  27. attach?: string
  28. removeFromParent?: () => void
  29. dispose?: () => void
  30. [prop: string]: any // for arbitrary properties
  31. }
  32. export interface LocalState {
  33. type: string
  34. // objects and parent are used when children are added with `attach` instead of being added to the Object3D scene graph
  35. objects: TresObject3D[]
  36. parent: TresObject3D | null
  37. primitive?: boolean
  38. eventCount: number
  39. handlers: Partial<EventHandlers>
  40. memoizedProps: { [key: string]: any }
  41. }
  42. // Custom type for geometry and material properties in Object3D
  43. export interface TresObject3D extends THREE.Object3D<THREE.Object3DEventMap> {
  44. geometry?: THREE.BufferGeometry & TresBaseObject
  45. material?: THREE.Material & TresBaseObject
  46. __tres: LocalState
  47. /* userData: {
  48. tres__materialViaProp: boolean
  49. tres__geometryViaProp: boolean
  50. [key: string]: any
  51. } */
  52. }
  53. export type TresObject = TresBaseObject & (TresObject3D | THREE.BufferGeometry | THREE.Material | THREE.Fog)
  54. export interface TresScene extends THREE.Scene {
  55. userData: {
  56. // keys are prefixed with tres__ to avoid name collisions
  57. tres__registerCamera?: (newCamera: THREE.Camera, active?: boolean) => void
  58. tres__deregisterCamera?: (camera: THREE.Camera) => void
  59. tres__registerAtPointerEventHandler?: (object: THREE.Object3D & PointerEventHandlerEventProps) => void
  60. tres__deregisterAtPointerEventHandler?: (object: THREE.Object3D) => void
  61. tres__registerBlockingObjectAtPointerEventHandler?: (object: THREE.Object3D) => void
  62. tres__deregisterBlockingObjectAtPointerEventHandler?: (object: THREE.Object3D) => void
  63. [key: string]: any
  64. }
  65. }
  66. // Events
  67. // eslint-disable-next-line import/namespace
  68. export interface Intersection extends THREE.Intersection {
  69. /** The event source (the object which registered the handler) */
  70. eventObject: TresObject
  71. }
  72. export interface IntersectionEvent<TSourceEvent> extends Intersection {
  73. /** The event source (the object which registered the handler) */
  74. eventObject: TresObject
  75. /** An array of intersections */
  76. intersections: Intersection[]
  77. /** vec3.set(pointer.x, pointer.y, 0).unproject(camera) */
  78. unprojectedPoint: THREE.Vector3
  79. /** Normalized event coordinates */
  80. pointer: THREE.Vector2
  81. /** Delta between first click and this event */
  82. delta: number
  83. /** The ray that pierced it */
  84. ray: THREE.Ray
  85. /** The camera that was used by the raycaster */
  86. camera: TresCamera
  87. /** stopPropagation will stop underlying handlers from firing */
  88. stopPropagation: () => void
  89. /** The original host event */
  90. nativeEvent: TSourceEvent
  91. /** If the event was stopped by calling stopPropagation */
  92. stopped: boolean
  93. }
  94. export type ThreeEvent<TEvent> = IntersectionEvent<TEvent> & Properties<TEvent>
  95. export type DomEvent = PointerEvent | MouseEvent | WheelEvent
  96. export interface Events {
  97. onClick: EventListener
  98. onContextMenu: EventListener
  99. onDoubleClick: EventListener
  100. onWheel: EventListener
  101. onPointerDown: EventListener
  102. onPointerUp: EventListener
  103. onPointerLeave: EventListener
  104. onPointerMove: EventListener
  105. onPointerCancel: EventListener
  106. onLostPointerCapture: EventListener
  107. }
  108. export interface EventHandlers {
  109. onClick?: (event: ThreeEvent<MouseEvent>) => void
  110. onContextMenu?: (event: ThreeEvent<MouseEvent>) => void
  111. onDoubleClick?: (event: ThreeEvent<MouseEvent>) => void
  112. onPointerUp?: (event: ThreeEvent<PointerEvent>) => void
  113. onPointerDown?: (event: ThreeEvent<PointerEvent>) => void
  114. onPointerOver?: (event: ThreeEvent<PointerEvent>) => void
  115. onPointerOut?: (event: ThreeEvent<PointerEvent>) => void
  116. onPointerEnter?: (event: ThreeEvent<PointerEvent>) => void
  117. onPointerLeave?: (event: ThreeEvent<PointerEvent>) => void
  118. onPointerMove?: (event: ThreeEvent<PointerEvent>) => void
  119. onPointerMissed?: (event: MouseEvent) => void
  120. onPointerCancel?: (event: ThreeEvent<PointerEvent>) => void
  121. onWheel?: (event: ThreeEvent<WheelEvent>) => void
  122. }
  123. interface MathRepresentation {
  124. set(...args: number[] | [THREE.ColorRepresentation]): any
  125. }
  126. interface VectorRepresentation extends MathRepresentation {
  127. setScalar(s: number): any
  128. }
  129. export interface VectorCoordinates {
  130. x: number
  131. y: number
  132. z: number
  133. }
  134. export type MathType<T extends MathRepresentation | THREE.Euler> = T extends THREE.Color
  135. ? ConstructorParameters<typeof THREE.Color> | THREE.ColorRepresentation
  136. // eslint-disable-next-line max-len
  137. : T extends VectorRepresentation | THREE.Layers | THREE.Euler ? T | Parameters<T['set']> | number | VectorCoordinates : T | Parameters<T['set']>
  138. export type TresVector2 = MathType<THREE.Vector2>
  139. export type TresVector3 = MathType<THREE.Vector3>
  140. export type TresVector4 = MathType<THREE.Vector4>
  141. export type TresColor = MathType<THREE.Color>
  142. export type TresLayers = MathType<THREE.Layers>
  143. export type TresQuaternion = MathType<THREE.Quaternion>
  144. export type TresEuler = MathType<THREE.Euler>
  145. type WithMathProps<P> = { [K in keyof P]: P[K] extends MathRepresentation | THREE.Euler ? MathType<P[K]> : P[K] }
  146. interface RaycastableRepresentation {
  147. raycast(raycaster: THREE.Raycaster, intersects: THREE.Intersection[]): void
  148. }
  149. type EventProps<P> = P extends RaycastableRepresentation ? Partial<EventHandlers> : unknown
  150. export interface VueProps<P> {
  151. children?: VNode[]
  152. ref?: VNodeRef
  153. key?: string | number | symbol
  154. }
  155. type ElementProps<T extends ConstructorRepresentation, P = InstanceType<T>> = Partial<
  156. Overwrite<WithMathProps<P>, VueProps<P> & EventProps<P>>
  157. >
  158. export type ThreeElement<T extends ConstructorRepresentation> = Mutable<
  159. Overwrite<ElementProps<T>, Omit<InstanceProps<InstanceType<T>, T>, 'object'>>
  160. >
  161. type ThreeExports = typeof THREE
  162. type ThreeInstancesImpl = {
  163. [K in keyof ThreeExports as Uncapitalize<K>]: ThreeExports[K] extends ConstructorRepresentation
  164. ? ThreeElement<ThreeExports[K]>
  165. : never
  166. }
  167. export interface ThreeInstances extends ThreeInstancesImpl {
  168. primitive: Omit<ThreeElement<any>, 'args'> & { object: object }
  169. }
  170. type TresComponents = {
  171. [K in keyof ThreeInstances as `Tres${Capitalize<string & K>}`]: DefineComponent<ThreeInstances[K]>
  172. }
  173. declare module 'vue' {
  174. export interface GlobalComponents extends TresComponents { }
  175. }
  176. /* eslint-enable @typescript-eslint/ban-types */