Jump to content

Cloning life cycle adjustments


JCPalmer
 Share

Recommended Posts

As of BJS 2.0, cloning was moved up into the constructor.  This enabled cloning of Mesh sub-classes.  I found still another issue trying implement a MeshFactory though:

    If the first instance, used as a reference for cloning, is disposed of, then _geometry = null;

 

This instance can no-longer be used for cloning, even though there could be other instances still using the geometry.  I would like to add a reference var, _geoRefForCloning, assigned the same value as _geometry.  This would be the variable used for cloning, and not set to null in dispose.

 

I have a work around for Tower of Babel, which I mocked up below, that puts _geoRefForCloning in the sub-class, but thought it seemed a bit forced.

// File generated with Tower of Babel version: 2.0.0 on 03/12/15module CheckBoxFont{    var meshLib = new Array<BABYLON.Mesh>(4);    var cloneCount = 1;    export class MeshFactory implements TOWER_OF_BABEL.FactoryModule {        constructor(private _scene : BABYLON.Scene, materialsRootDir: string = "./") {            CheckBoxFont.defineMaterials(_scene, materialsRootDir); //embedded version check        }        public getModuleName() : string { return "CheckBoxFont";}        public instance(meshName : string, cloneSkeleton? : boolean) : BABYLON.Mesh {            var ret:BABYLON.Mesh = null;            var src:BABYLON.Mesh;            switch (meshName){                case "unchecked2D":                    src = meshLib[0];                    if (!src || src === null){                        ret = new unchecked2D("unchecked2D", this._scene);                        meshLib[0] = ret;                    }else ret = new unchecked2D("unchecked2D" + "_" + cloneCount++, this._scene, null, <unchecked2D> src);                    break;                    ...            }            if (ret !== null){                if (cloneSkeleton && src && src.skeleton){                    var skelName = src.skeleton.name + cloneCount;                    ret.skeleton = src.skeleton.clone(skelName, skelName);                }            }            else BABYLON.Tools.Error("Mesh not found: " + meshName);            return ret;        }    }    export class unchecked2D extends DIALOG.Letter {        public _geoRefForCloning : any;                constructor(name: string, scene: BABYLON.Scene, materialsRootDir: string = "./", source? : unchecked2D) {            super(name, scene, null, source, true);            CheckBoxFont.defineMaterials(scene, materialsRootDir); //embedded version check                        var cloning = source && source !== null;            if (cloning){                if (!this.geometry){                    source._geoRefForCloning.applyToMesh(this);                }            } else {                this._geoRefForCloning = this.geometry;            }            ...        }        public dispose(doNotRecurse?: boolean): void {            super.dispose(doNotRecurse);            if (this._geoRefForCloning.isDisposed() ) meshLib[0] = null;        }    }    ...}
Link to comment
Share on other sites

Well, have found a better solution, but still without modifying BJS.  Output can still work with BJS 2.0.  FYI:

 

Changed module internal array of references to clone to an array of arrays.  Object references are cheap, but now can draw on any still living mesh for geometry:

var meshLib = new Array<Array<BABYLON.Mesh>>(number_of_clonable_meshes);

Added 2 module internal functions to get a mesh for cloning & cleaning up:

function getViable(libIdx : number) : BABYLON.Mesh {    var meshes = meshLib[libIdx];    if (!meshes  || meshes === null){        if (!meshes) meshLib[libIdx] = new Array<BABYLON.Mesh>();        return null;    }            for (var i = meshes.length - 1; i >= 0; i--){        if (meshes[i].geometry) return meshes[i];    }    return null;}function clean(libIdx : number) : void {    var meshes = meshLib[libIdx];    if (!meshes  || meshes === null) return;           var stillViable = false;    for (var i = meshes.length - 1; i >= 0; i--){        if (!meshes[i].geometry) meshes[i] = null;        else stillViable = true;    }    if (!stillViable) meshLib[libIdx] = null;}

The case for getting an instance of each class was changed slightly to:

case "unchecked2D":    src = getViable(0);    if (src === null){        ret = new unchecked2D("unchecked2D", this._scene);        meshLib[0].push(ret);    }else ret = new unchecked2D("unchecked2D" + "_" + cloneCount++, this._scene, null, <unchecked2D> src);    break;

Finally, overridden dispose() in each class now:

public dispose(doNotRecurse?: boolean): void {    super.dispose(doNotRecurse);    clean(0);}

These changes were done manually to a previously generated source file.  Think Tower of Babel 2.0 will finally be done once this is implemented in python.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...