Using scaleToRef stops the Playground

Even though there are many loops this PG which calls scale on Vector2 runs well https://playground.babylonjs.com/#QYBWV4#52

However even though scale calls scaleToRef using scaleToRef stops the PG.
These are the changes I am making. If you copy and paste the changes into the PG it will keep stopping

const collectUV = (A, B) => {
        const AStart = BABYLON.Vector2.Zero();
        const Aunit = BABYLON.Vector2.Zero();
        const Bunit = BABYLON.Vector2.Zero();
        BABYLON.Vector2.NormalizeToRef(A, Aunit);
        BABYLON.Vector2.NormalizeToRef(B, Bunit);
        const Alen = A.length();
        const Blen = B.length();
        for (Ascale = 0; Ascale <= 1; Ascale += 0.001) {
            for (Bscale = 0; Bscale <= 1; Bscale += 0.001) {
                //scale Aunit and Bunit
                const Bend = AStart;
                const deltaBend = BABYLON.Vector2.Zero();
                Aunit.scaleToRef(Ascale * Alen, deltaBend);
                Bend.addInPlace(deltaBend);
                Bunit.scaleToRef(Bscale * Ascale * Blen, deltaBend);
                Bend.addInPlace(deltaBend);
                const Bgrid = mapVecToGrid(Bend);
                const uv = mapGridvecToUV(Bgrid);
                const index = mapGridvecToIndex(Bgrid);
                uv.toArray(uvs, 2 * index);
            }
        }
        ground.setVerticesData(BABYLON.VertexBuffer.UVKind, uvs);
    }

The stopping problem also happens when using scaleAndAddToRef

Hey John! It seems that the algorithm with ScaleToRef is slightly different than the one with Scale, as if I reduce the Ascale and Bscale a bit to have fewer iterations, they have different visual results:
image
Left is scale, right is scaleToRef.

I think this is more likely to cause the out of memory error that’s stopping the PG.

You are converting:

const Bend = AStart.add(Aunit.scale(Ascale * Alen)).add(Bunit.scale(Bscale * Ascale * Blen));

to

const Bend = AStart;
const deltaBend = BABYLON.Vector2.Zero();
Aunit.scaleToRef(Ascale * Alen, deltaBend);
Bend.addInPlace(deltaBend);
Bunit.scaleToRef(Bscale * Ascale * Blen, deltaBend);
Bend.addInPlace(deltaBend);

so AStart in the second version will be modified each iteration :slight_smile:

You could try smthg like this:

        const Alen = A.length();
        const Blen = B.length();
       
        const Bend = BABYLON.Vector2.Zero();
        const deltaBend = BABYLON.Vector2.Zero();
       
        for (Ascale = 0; Ascale <= 1; Ascale += 0.001) {
            for (Bscale = 0; Bscale <= 1; Bscale += 0.001) {
                // Reset State.
                Bend.copyFrom(AStart);
                deltaBend.x = deltaBend.y = 0;

                Aunit.scaleToRef(Ascale * Alen, deltaBend);
                Bend.addInPlace(deltaBend);
                Bunit.scaleToRef(Bscale * Ascale * Blen, deltaBend);
                Bend.addInPlace(deltaBend);

                const Bgrid = mapVecToGrid(Bend);
                const uv = mapGridvecToUV(Bgrid);
                const index = mapGridvecToIndex(Bgrid);
                uv.toArray(uvs, 2 * index);
            }
        }
2 Likes

@sebavan thank you, obvious now you point it out.

1 Like