import { Reference } from "../serialization/Reference" ; import { Material } from "./Material" ; import { Geometry , GraphicUpdateResult } from "./geometry/Geometry" ; import { AssetReference } from "../serialization/AssetReference" ; import { Camera } from "./camera/Camera" ; import { VisualGroup } from "./VisualGroup" ; import { SkinnedMesh } from "./geometry/SkinnedMesh" ; import { SerializedObject } from "../core/SerializableObject" ; import { Component } from "../core/Component" ; import { ObjectProps } from "../core/Types" ; import { Entity } from "../core/Entity" ; import { Transform } from "../core/Transform" ; import * as Attributes from "../core/Attributes" ; import { Texture } from "./texture/Texture" ; @ Attributes . helpUrl ( "https://docs.spiderengine.io/3d/visual.html" ) export class Visual extends Component { get version ( ) { return 5 ; } get material ( ) { return this . _material . asset ; } get geometry ( ) { return this . _geometry . instance ; } get group ( ) { return this . _group . asset ; } get castShadows ( ) { return this . _castShadows ; } set castShadows ( cast ) { this . _castShadows = cast ; } get receiveShadows ( ) { return this . _receiveShadows ; } set receiveShadows ( receive ) { this . _receiveShadows = receive ; } get receiveFog ( ) { return this . _receiveFog ; } set receiveFog ( receive ) { this . _receiveFog = receive ; } set geometry ( geometry ) { this . _geometry . instance = geometry ; } set material ( material ) { this . _material . asset = material ; } set group ( group ) { this . _group . asset = group ; } get vertexBuffer ( ) { return this . geometry ?. getVertexBuffer ( ) ?? null ; } get animatedMaterial ( ) { return this . _uniqueAnimatedMaterialInstance ; } set animatedMaterial ( animatedMaterial ) { this . _uniqueAnimatedMaterialInstance = animatedMaterial ; } get envMap ( ) { return this . _envMap ; } set envMap ( envMap ) { this . _envMap = envMap ; } get worldTransform ( ) { return this . geometry ?. getWorldTransform ( this . entity . transform ) ?? this . entity . transform . worldMatrix ; } get bucketId ( ) { let id = 0 ; if ( this . _receiveShadows ) { id = 1 ; } if ( this . _receiveFog ) { id |= 1 << 1 ; } if ( this . isSkinned ) { id |= 1 << 2 ; } if ( this . hasVertexColor ) { id |= 1 << 3 ; } if ( this . _envMap ) { id |= 1 << 4 ; } if ( this . hasNormalMap ) { id |= 1 << 5 ; } return `${ id }` ; } get isSkinned ( ) { return Boolean ( this . geometry ?. isA ( SkinnedMesh ) ) ; } get isReflective ( ) { return ( ( this . material ?. shaderParams as any ) . reflectivity ?? 0 ) > 0 ; } get hasNormalMap ( ) { return Boolean ( ( this . material ?. shaderParams as any ) ?. normalMap ?. asset ) ; } get hasVertexColor ( ) { return Boolean ( this . geometry ?. getVertexBuffer ( ) ?. hasAttribute ( "color" ) ) ; } private _castShadows = true ; private _receiveShadows = true ; private _receiveFog = true ; private _group = new AssetReference ( VisualGroup ) ; private _geometry = new Reference ( Geometry ) ; private _material = new AssetReference ( Material ) ; @ Attributes . unserializable ( ) @ Attributes . hidden ( ) private _uniqueAnimatedMaterialInstance ? : Material ; @ Attributes . unserializable ( ) private _envMap : Texture | null = null ; constructor ( props ? ) { super ( ) ; if ( props ) { this . setState ( props ) ; } } setEntity ( entity ) { super . setEntity ( entity ) ; entity . getOrSetComponent ( Transform ) ; } graphicUpdate ( camera ) { return this . geometry ?. graphicUpdate ( camera , this . entity . transform ) ?? GraphicUpdateResult . Unchanged ; } destroy ( ) { this . geometry ?. destroy ( ) ; this . _uniqueAnimatedMaterialInstance ?. destroy ( ) ; this . _material . detach ( ) ; this . _group . detach ( ) ; super . destroy ( ) ; } upgrade ( json , previousVersion ) { if ( previousVersion === 1 ) { Object . assign ( json . properties , { _group : json . properties . group , _material : json . properties . material } ) ; let geometry = json . properties . geometry . data ; if ( geometry && geometry . typeName !== "Particles" ) { Object . assign ( json . properties , { _geometry : json . properties . geometry , } ) ; } delete json . properties . group ; delete json . properties . material ; delete json . properties . geometry ; } else if ( previousVersion === 2 ) { const geometryData = json . properties . _geometry . data ; if ( geometryData && geometryData . typeName === "SkyBox" ) { delete json . properties . _geometry . data ; } } else if ( previousVersion === 3 ) { const geometryData = json . properties . _geometry . data ; if ( geometryData && geometryData . typeName === "Quad" ) { geometryData . typeName = "QuadGeometry" ; } } else if ( previousVersion === 4 ) { Object . assign ( json . properties , { _castShadows : json . properties . castShadows , _receiveShadows : json . properties . receiveShadows , _receiveFog : json . properties . receiveFog } ) ; delete json . properties . castShadows ; delete json . properties . receiveShadows ; delete json . properties . receiveFog ; } return json ; } }