<commit_before>import { Object3D, BufferGeometry, BufferAttribute, MeshBasicMaterial, AnimationMixer, DataTexture, MathUtils, RGBAFormat, FloatType, RGBFormat, Points, Color, Matrix4 } from '../../../three/src/Three.js';
import TransformShader from '../../core/shader/TransformShader.js';
import Ticker from '../../core/util/Ticker.js';
import THREEGPGPUSystem from '../../three/gpgpu/THREEGPGPUSystem.js';
import THREEShaderMaterial from '../../three/material/THREEShaderMaterial.js';

export default class THREEMotionVectorObject extends Object3D {
  constructor({
    renderer,
    gltfData,
    pointsAttributes = undefined,
    material = new THREEShaderMaterial({
      skinning: true,
      type: 'basic',
      uniforms: {
        diffuse: new Color('#ff0000'),
      },
      vertexChunks: [
        ['main', `
          gl_PointSize = 2.;
        `],
      ],
    }),
  }) {
    super();

    this._initialized = false;

    const object = gltfData.scene;
    this._mesh = object;
    object.traverse((object) => {
      if (object.skeleton) {
        this._mesh = object;
      }
    });
    this._mesh.visible = false;
    if (!pointsAttributes) {
      pointsAttributes = new Map();
      for (const [name, value] of Object.entries(this._mesh.geometry.attributes)) {
        pointsAttributes.set(name, {
          data: value.array,
          size: value.itemSize,
        });
      }
    }
    this.add(object);

    this._skeleton = this._mesh.skeleton;

    // Create bonesTexture manually
    // https://github.com/mrdoob/three.js/blob/cd41804aa436bb2cfd79797c04985f75c4c63e63/src/renderers/WebGLRenderer.js#L1632

    let size = Math.sqrt(this._skeleton.bones.length * 4); // 4 pixels needed for 1 matrix
    size = MathUtils.ceilPowerOfTwo(size);
    size = Math.max(size, 4);

    const boneMatrices = new Float32Array(size * size * 4); // 4 floats per RGBA pixel
    boneMatrices.set(this._skeleton.boneMatrices); // copy current values

    const boneTexture = new DataTexture(boneMatrices, size, size, RGBAFormat, FloatType);

    this._skeleton.boneMatrices = boneMatrices;
    this._skeleton.boneTexture = boneTexture;
    this._skeleton.boneTextureSize = size;

    //

    const geometry = new BufferGeometry();

    for (const [name, attributeData] of pointsAttributes) {
      if (!this._pointCount) {
        this._pointCount = attributeData.data.length / attributeData.size;
      }
      geometry.setAttribute(name, new BufferAttribute(attributeData.data, attributeData.size));
    }
<commit_msg>THREEMotionVectorObject: allow max point count<commit_after>import { Object3D, BufferGeometry, BufferAttribute, MeshBasicMaterial, AnimationMixer, DataTexture, MathUtils, RGBAFormat, FloatType, RGBFormat, Points, Color, Matrix4 } from '../../../three/src/Three.js';
import TransformShader from '../../core/shader/TransformShader.js';
import Ticker from '../../core/util/Ticker.js';
import THREEGPGPUSystem from '../../three/gpgpu/THREEGPGPUSystem.js';
import THREEShaderMaterial from '../../three/material/THREEShaderMaterial.js';

export default class THREEMotionVectorObject extends Object3D {
  constructor({
    renderer,
    gltfData,
    pointsAttributes = undefined,
    material = new THREEShaderMaterial({
      skinning: true,
      type: 'basic',
      uniforms: {
        diffuse: new Color('#ff0000'),
      },
      vertexChunks: [
        ['main', `
          gl_PointSize = 2.;
        `],
      ],
    }),
    pointCount = undefined,
  }) {
    super();

    this._pointCount = pointCount;

    this._initialized = false;

    const object = gltfData.scene;
    this._mesh = object;
    object.traverse((object) => {
      if (object.skeleton) {
        this._mesh = object;
      }
    });
    this._mesh.visible = false;
    if (!pointsAttributes) {
      pointsAttributes = new Map();
      for (const [name, value] of Object.entries(this._mesh.geometry.attributes)) {
        pointsAttributes.set(name, {
          data: value.array,
          size: value.itemSize,
        });
      }
    }
    this.add(object);

    if (this._pointCount) {
      for (const attributeData of pointsAttributes.values()) {
        const newArray = new attributeData.data.constructor(this._pointCount * attributeData.size);
        const stride = attributeData.size;
        const difference = Math.floor(attributeData.data.length / newArray.length);
        for (let index = 0; index < this._pointCount; index++) {
          for (let componentIndex = 0; componentIndex < stride; componentIndex++) {
            newArray[index * stride + componentIndex] = attributeData.data[index * stride * difference + componentIndex];
          }
        }
        attributeData.data = newArray;
      }
    } else {
      const firstAttribute = pointsAttributes.values().next().value;
      this._pointCount = firstAttribute.data.length / firstAttribute.size;
    }

    this._skeleton = this._mesh.skeleton;

    // Create bonesTexture manually
    // https://github.com/mrdoob/three.js/blob/cd41804aa436bb2cfd79797c04985f75c4c63e63/src/renderers/WebGLRenderer.js#L1632

    let size = Math.sqrt(this._skeleton.bones.length * 4); // 4 pixels needed for 1 matrix
    size = MathUtils.ceilPowerOfTwo(size);
    size = Math.max(size, 4);

    const boneMatrices = new Float32Array(size * size * 4); // 4 floats per RGBA pixel
    boneMatrices.set(this._skeleton.boneMatrices); // copy current values

    const boneTexture = new DataTexture(boneMatrices, size, size, RGBAFormat, FloatType);

    this._skeleton.boneMatrices = boneMatrices;
    this._skeleton.boneTexture = boneTexture;
    this._skeleton.boneTextureSize = size;

    //

    const geometry = new BufferGeometry();

    for (const [name, attributeData] of pointsAttributes) {
      geometry.setAttribute(name, new BufferAttribute(attributeData.data, attributeData.size));
    }

{'fraction_non_alphanumeric': 0.12216345333560825, 'fraction_numerical': 0.016038218734004437, 'mean_word_length': 2.939516129032258, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 5, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1078487', 'n_tokens_mistral': 1787, 'n_tokens_neox': 1716, 'n_words': 370}