{"version":3,"file":"MD2Character.cjs","sources":["../../src/misc/MD2Character.js"],"sourcesContent":["import { AnimationMixer, Box3, Mesh, MeshLambertMaterial, Object3D, TextureLoader, UVMapping } from 'three'\nimport { MD2Loader } from '../loaders/MD2Loader'\n\nclass MD2Character {\n  constructor() {\n    this.scale = 1\n    this.animationFPS = 6\n\n    this.root = new Object3D()\n\n    this.meshBody = null\n    this.meshWeapon = null\n\n    this.skinsBody = []\n    this.skinsWeapon = []\n\n    this.weapons = []\n\n    this.activeAnimation = null\n\n    this.mixer = null\n\n    this.onLoadComplete = function () {}\n\n    this.loadCounter = 0\n  }\n\n  loadParts(config) {\n    const scope = this\n\n    function createPart(geometry, skinMap) {\n      const materialWireframe = new MeshLambertMaterial({\n        color: 0xffaa00,\n        wireframe: true,\n        morphTargets: true,\n        morphNormals: true,\n      })\n      const materialTexture = new MeshLambertMaterial({\n        color: 0xffffff,\n        wireframe: false,\n        map: skinMap,\n        morphTargets: true,\n        morphNormals: true,\n      })\n\n      //\n\n      const mesh = new Mesh(geometry, materialTexture)\n      mesh.rotation.y = -Math.PI / 2\n\n      mesh.castShadow = true\n      mesh.receiveShadow = true\n\n      //\n\n      mesh.materialTexture = materialTexture\n      mesh.materialWireframe = materialWireframe\n\n      return mesh\n    }\n\n    function loadTextures(baseUrl, textureUrls) {\n      const textureLoader = new TextureLoader()\n      const textures = []\n\n      for (let i = 0; i < textureUrls.length; i++) {\n        textures[i] = textureLoader.load(baseUrl + textureUrls[i], checkLoadingComplete)\n        textures[i].mapping = UVMapping\n        textures[i].name = textureUrls[i]\n        if ('colorSpace' in textures[i]) textures[i].colorSpace = 'srgb'\n        else textures[i].encoding = 3001 // sRGBEncoding\n      }\n\n      return textures\n    }\n\n    function checkLoadingComplete() {\n      scope.loadCounter -= 1\n\n      if (scope.loadCounter === 0) scope.onLoadComplete()\n    }\n\n    this.loadCounter = config.weapons.length * 2 + config.skins.length + 1\n\n    const weaponsTextures = []\n    for (let i = 0; i < config.weapons.length; i++) weaponsTextures[i] = config.weapons[i][1]\n    // SKINS\n\n    this.skinsBody = loadTextures(config.baseUrl + 'skins/', config.skins)\n    this.skinsWeapon = loadTextures(config.baseUrl + 'skins/', weaponsTextures)\n\n    // BODY\n\n    const loader = new MD2Loader()\n\n    loader.load(config.baseUrl + config.body, function (geo) {\n      const boundingBox = new Box3()\n      boundingBox.setFromBufferAttribute(geo.attributes.position)\n\n      scope.root.position.y = -scope.scale * boundingBox.min.y\n\n      const mesh = createPart(geo, scope.skinsBody[0])\n      mesh.scale.set(scope.scale, scope.scale, scope.scale)\n\n      scope.root.add(mesh)\n\n      scope.meshBody = mesh\n\n      scope.meshBody.clipOffset = 0\n      scope.activeAnimationClipName = mesh.geometry.animations[0].name\n\n      scope.mixer = new AnimationMixer(mesh)\n\n      checkLoadingComplete()\n    })\n\n    // WEAPONS\n\n    const generateCallback = function (index, name) {\n      return function (geo) {\n        const mesh = createPart(geo, scope.skinsWeapon[index])\n        mesh.scale.set(scope.scale, scope.scale, scope.scale)\n        mesh.visible = false\n\n        mesh.name = name\n\n        scope.root.add(mesh)\n\n        scope.weapons[index] = mesh\n        scope.meshWeapon = mesh\n\n        checkLoadingComplete()\n      }\n    }\n\n    for (let i = 0; i < config.weapons.length; i++) {\n      loader.load(config.baseUrl + config.weapons[i][0], generateCallback(i, config.weapons[i][0]))\n    }\n  }\n\n  setPlaybackRate(rate) {\n    if (rate !== 0) {\n      this.mixer.timeScale = 1 / rate\n    } else {\n      this.mixer.timeScale = 0\n    }\n  }\n\n  setWireframe(wireframeEnabled) {\n    if (wireframeEnabled) {\n      if (this.meshBody) this.meshBody.material = this.meshBody.materialWireframe\n      if (this.meshWeapon) this.meshWeapon.material = this.meshWeapon.materialWireframe\n    } else {\n      if (this.meshBody) this.meshBody.material = this.meshBody.materialTexture\n      if (this.meshWeapon) this.meshWeapon.material = this.meshWeapon.materialTexture\n    }\n  }\n\n  setSkin(index) {\n    if (this.meshBody && this.meshBody.material.wireframe === false) {\n      this.meshBody.material.map = this.skinsBody[index]\n    }\n  }\n\n  setWeapon(index) {\n    for (let i = 0; i < this.weapons.length; i++) this.weapons[i].visible = false\n\n    const activeWeapon = this.weapons[index]\n\n    if (activeWeapon) {\n      activeWeapon.visible = true\n      this.meshWeapon = activeWeapon\n\n      this.syncWeaponAnimation()\n    }\n  }\n\n  setAnimation(clipName) {\n    if (this.meshBody) {\n      if (this.meshBody.activeAction) {\n        this.meshBody.activeAction.stop()\n        this.meshBody.activeAction = null\n      }\n\n      const action = this.mixer.clipAction(clipName, this.meshBody)\n\n      if (action) {\n        this.meshBody.activeAction = action.play()\n      }\n    }\n\n    this.activeClipName = clipName\n\n    this.syncWeaponAnimation()\n  }\n\n  syncWeaponAnimation() {\n    const clipName = this.activeClipName\n\n    if (this.meshWeapon) {\n      if (this.meshWeapon.activeAction) {\n        this.meshWeapon.activeAction.stop()\n        this.meshWeapon.activeAction = null\n      }\n\n      const action = this.mixer.clipAction(clipName, this.meshWeapon)\n\n      if (action) {\n        this.meshWeapon.activeAction = action.syncWith(this.meshBody.activeAction).play()\n      }\n    }\n  }\n\n  update(delta) {\n    if (this.mixer) this.mixer.update(delta)\n  }\n}\n\nexport { MD2Character }\n"],"names":["Object3D","MeshLambertMaterial","Mesh","TextureLoader","UVMapping","MD2Loader","Box3","AnimationMixer"],"mappings":"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"}