scaled static method

ModelData scaled(
  1. ModelData data,
  2. double s
)

data with every length multiplied by s: vertex positions, node and joint translations, animated translations, bounds and light ranges.

Implementation

static ModelData scaled(ModelData data, double s) {
  Aabb3 box(Aabb3 b) =>
      b.isEmpty ? Aabb3() : Aabb3.minMax(b.min * s, b.max * s);
  Matrix4 moved(Matrix4 m) {
    final out = Matrix4.copy(m);
    out.storage[12] *= s;
    out.storage[13] *= s;
    out.storage[14] *= s;
    return out;
  }

  final meshes = [
    for (final mesh in data.meshes)
      MeshData(mesh.name, [
        for (final p in mesh.primitives)
          PrimitiveData(
            vertices: () {
              final v = Float32List.fromList(p.vertices);
              for (var i = 0; i + 2 < v.length; i += kVertexFloats) {
                v[i] *= s;
                v[i + 1] *= s;
                v[i + 2] *= s;
              }
              return v;
            }(),
            indices: p.indices,
            material: p.material,
            bounds: box(p.bounds),
            hasTangents: p.hasTangents,
            skin: p.skin,
          ),
      ]),
  ];
  final nodes = [
    for (final n in data.nodes)
      NodeData(
        name: n.name,
        local: moved(n.local),
        children: n.children,
        mesh: n.mesh,
        skin: n.skin,
        light: n.light,
        translation: n.translation == null ? null : n.translation! * s,
        rotation: n.rotation,
        scale: n.scale,
      ),
  ];
  final skins = [
    for (final skin in data.skins)
      SkinData(
        name: skin.name,
        joints: skin.joints,
        skeleton: skin.skeleton,
        inverseBindMatrices: () {
          final m = Float32List.fromList(skin.inverseBindMatrices);
          for (var j = 0; j + 15 < m.length; j += 16) {
            m[j + 12] *= s;
            m[j + 13] *= s;
            m[j + 14] *= s;
          }
          return m;
        }(),
      ),
  ];
  final animations = [
    for (final a in data.animations)
      AnimationData(
        name: a.name,
        duration: a.duration,
        channels: a.channels,
        samplers: [
          for (var i = 0; i < a.samplers.length; i++)
            a.channels.any(
                  (c) =>
                      c.sampler == i && c.path == AnimationPath.translation,
                )
                ? AnimationSamplerData(
                    input: a.samplers[i].input,
                    output: Float32List.fromList([
                      for (final v in a.samplers[i].output) v * s,
                    ]),
                    interpolation: a.samplers[i].interpolation,
                    width: a.samplers[i].width,
                  )
                : a.samplers[i],
        ],
      ),
  ];
  final lights = [
    for (final l in data.lights)
      LightData(
        type: l.type,
        name: l.name,
        color: l.color,
        intensity: l.intensity,
        range: l.range == null ? null : l.range! * s,
        innerConeAngle: l.innerConeAngle,
        outerConeAngle: l.outerConeAngle,
      ),
  ];
  return ModelData(
    name: data.name,
    meshes: meshes,
    materials: data.materials,
    textures: data.textures,
    images: data.images,
    nodes: nodes,
    roots: data.roots,
    lights: lights,
    bounds: box(data.bounds),
    skins: skins,
    animations: animations,
    warnings: data.warnings,
  );
}