<commit_before>pc.extend(pc.fw, function() {

    // properties that do not need rebuilding the particle system
    var SIMPLE_PROPERTIES = [
        'spawnBounds',
        'speedDiv',
        'constantSpeedDiv',
        'colorMap',
        'normalMap'
    ];

    // properties that need rebuilding the particle system
    var COMPLEX_PROPERTIES = [
        'numParticles',
        'lifetime',
        'rate',
        'smoothness',
        'lighting',
        'halfLambert',
        'wrap',
        'wrapBounds',
        'depthTest',
        'depthSoftening',
        'gammaCorrect',
        'sort',
        'stretch',
        'maxEmissionTime',
        'localOffsetGraph',
        'offsetGraph',
        'angleGraph',
        'scaleGraph',
        'colorGraph',
        'alphaGraph',
        'localPosDivGraph',
        'posDivGraph',
        'scaleDivGraph',
        'angleDivGraph',
        'alphaDivGraph',
        'camera'
    ];

    var ParticleSystemComponent = function ParticleSystemComponent(system, entity) {
        this.on("set_colorMapAsset", this.onSetColorMapAsset, this);
        this.on("set_normalMapAsset", this.onSetNormalMapAsset, this);
        this.on("set_mesh", this.onSetMesh, this);
        this.on("set_oneShot", this.onSetOneShot, this);

        SIMPLE_PROPERTIES.forEach(function (prop) {
            this.on('set_' + prop, this.onSetSimpleProperty, this);
        }.bind(this));

        COMPLEX_PROPERTIES.forEach(function (prop) {
            this.on('set_' + prop, this.onSetComplexProperty, this);
        }.bind(this));
    };

    ParticleSystemComponent = pc.inherits(ParticleSystemComponent, pc.fw.Component);

    pc.extend(ParticleSystemComponent.prototype, {

        onSetColorMapAsset: function (name, oldValue, newValue) {
            if (newValue) {
                this._loadAsset(newValue, function (resource) {
                    this.colorMap = resource;
                }.bind(this));
            } else {
                this.colorMap = null;
            }
        },

        onSetNormalMapAsset: function (name, oldValue, newValue) {
            if (newValue) {
                this._loadAsset(newValue, function (resource) {
                    this.normalMap = resource;
                }.bind(this));
            } else {
                this.normalMap = null;
            }
        },

        _loadAsset: function (assetId, callback) {
            var asset = (assetId instanceof pc.asset.Asset ? assetId : this.system.context.assets.getAssetById(assetId));
            if (!asset) {
                logERROR(pc.string.format('Trying to load particle system before asset {0} is loaded.', assetId));
                return;
            }

            // try to load the cached asset first
            var resource;
            if (asset.resource) {
                callback(asset.resource);

            } else {
                // resource is not in cache so load it dynamically
                var options = {
                    parent: this.entity.getRequest()
                };

                this.system.context.assets.load(asset, [], options).then(function (resources) {
                    callback(resources[0]);
                });
            }
        },

        onSetMesh: function (name, oldValue, newValue) {
            if (newValue) {
                if (newValue instanceof pc.asset.Asset || pc.type(newValue) === 'number') {
                    // asset
                    this._loadAsset(newValue, function (model) {
                        this._onMeshChanged(model);
                    }.bind(this));
                } else {
                    // model resource
                    this._onMeshChanged(newValue);
                }
            } else {
                // null model
                this._onMeshChanged(null);
            }
        },

        _onMeshChanged: function (mesh) {
            if (mesh) {
                if (mesh.meshInstances[0]) {
                    mesh = mesh.meshInstances[0].mesh;
                } else {
                    mesh = null;
                }
            }

            this.data.mesh = mesh;

            if (this.emitter) {
                this.emitter.mesh = mesh;
                this.emitter.resetMaterial();
                this.rebuild();
            }
        },

        onSetOneShot: function (name, oldValue, newValue) {
            if (this.emitter) {
                this.emitter[name] = newValue;
                this.emitter.resetTime();
            }
        },

        onSetSimpleProperty: function (name, oldValue, newValue) {
            if (this.emitter) {
                this.emitter[name] = newValue;
                this.emitter.resetMaterial();
            }
        },

        onSetComplexProperty: function (name, oldValue, newValue) {
            if (this.emitter) {
                this.emitter[name] = newValue;
                this.emitter.resetMaterial();
                this.rebuild();
            }
        },

        onEnable: function() {
            if (!this.emitter && !this.system._inTools) {

                this.emitter = new pc.scene.ParticleEmitter2(this.system.context.graphicsDevice, {
                    numParticles: this.data.numParticles,
                    spawnBounds: this.data.spawnBounds,
                    wrap: this.data.wrap,
                    wrapBounds: this.data.wrapBounds,
                    lifetime: this.data.lifetime,
                    rate: this.data.rate,
                    localOffsetGraph: this.data.localOffsetGraph,
                    offsetGraph: this.data.offsetGraph,
                    angleGraph: this.data.angleGraph,
                    scaleGraph: this.data.scaleGraph,
                    colorGraph: this.data.colorGraph,
                    alphaGraph: this.data.alphaGraph,
                    localPosDivGraph: this.data.localPosDivGraph,
                    posDivGraph: this.data.posDivGraph,
                    scaleDiv: this.data.scaleDiv,
                    angleDivGraph: this.data.angleDivGraph,
                    alphaDivGraph: this.data.alphaDivGraph,
                    colorMap: this.data.colorMap,
                    normalMap: this.data.normalMap,
                    oneShot: this.data.oneShot,
                    speedDiv: this.data.speedDiv,
                    constantSpeedDiv: this.data.constantSpeedDiv,
                    sort: this.data.sort,
                    stretch: this.data.stretch,
                    lighting: this.data.lighting,
                    halfLambert: this.data.halfLambert,
                    maxEmissionTime: this.data.maxEmissionTime,
                    depthSoftening: this.data.depthSoftening,
                    camera: this.data.camera,
                    scene: this.system.context.scene,
                    mesh: this.data.mesh,
                    depthTest: this.data.depthTest,
                    gammaCorrect: this.data.gammaCorrect,
                    smoothness: this.data.smoothness
                });
                this.emitter.meshInstance.node = this.entity;

                this.psys = new pc.scene.Model();
                this.psys.graph = this.entity;
                this.psys.emitter = this.emitter;
                this.psys.meshInstances = [this.emitter.meshInstance];
                this.data.model = this.psys;
                this.emitter.psys = this.psys;

                // called after oneShot emitter is finished. As you can dynamically change oneShot parameter, it should be always initialized
				this.emitter.onFinished = function() {
					this.enabled = false;
				}.bind(this);
            }


            ParticleSystemComponent._super.onEnable.call(this);
            if (this.data.model) {
                if (!this.system.context.scene.containsModel(this.data.model)) {
                    if (this.emitter.colorMap) {
                        this.system.context.scene.addModel(this.data.model);
                    }
                }
            }
        },

        onDisable: function() {
            ParticleSystemComponent._super.onDisable.call(this);
            if (this.data.model) {
                if (this.system.context.scene.containsModel(this.data.model)) {
                    this.system.context.scene.removeModel(this.data.model);
                }
            }
        },

        reset: function() {
            this.emitter.reset();
        },

        rebuild: function() {
            var enabled = this.enabled;
            this.enabled = false;
            this.emitter.rebuild(); // worst case: required to rebuild buffers/shaders
            this.emitter.meshInstance.node = this.entity;
            this.data.model.meshInstances = [this.emitter.meshInstance];
            this.enabled = enabled;
        },
    });


    return {
        ParticleSystemComponent: ParticleSystemComponent
    };
}());
<commit_msg>Try to get a valid camera when the particle system is enabled<commit_after>pc.extend(pc.fw, function() {

    // properties that do not need rebuilding the particle system
    var SIMPLE_PROPERTIES = [
        'spawnBounds',
        'speedDiv',
        'constantSpeedDiv',
        'colorMap',
        'normalMap'
    ];

    // properties that need rebuilding the particle system
    var COMPLEX_PROPERTIES = [
        'numParticles',
        'lifetime',
        'rate',
        'smoothness',
        'lighting',
        'halfLambert',
        'wrap',
        'wrapBounds',
        'depthTest',
        'depthSoftening',
        'gammaCorrect',
        'sort',
        'stretch',
        'maxEmissionTime',
        'localOffsetGraph',
        'offsetGraph',
        'angleGraph',
        'scaleGraph',
        'colorGraph',
        'alphaGraph',
        'localPosDivGraph',
        'posDivGraph',
        'scaleDivGraph',
        'angleDivGraph',
        'alphaDivGraph',
        'camera'
    ];

    var ParticleSystemComponent = function ParticleSystemComponent(system, entity) {
        this.on("set_colorMapAsset", this.onSetColorMapAsset, this);
        this.on("set_normalMapAsset", this.onSetNormalMapAsset, this);
        this.on("set_mesh", this.onSetMesh, this);
        this.on("set_oneShot", this.onSetOneShot, this);

        SIMPLE_PROPERTIES.forEach(function (prop) {
            this.on('set_' + prop, this.onSetSimpleProperty, this);
        }.bind(this));

        COMPLEX_PROPERTIES.forEach(function (prop) {
            this.on('set_' + prop, this.onSetComplexProperty, this);
        }.bind(this));
    };

    ParticleSystemComponent = pc.inherits(ParticleSystemComponent, pc.fw.Component);

    pc.extend(ParticleSystemComponent.prototype, {

        onSetColorMapAsset: function (name, oldValue, newValue) {
            if (newValue) {
                this._loadAsset(newValue, function (resource) {
                    this.colorMap = resource;
                }.bind(this));
            } else {
                this.colorMap = null;
            }
        },

        onSetNormalMapAsset: function (name, oldValue, newValue) {
            if (newValue) {
                this._loadAsset(newValue, function (resource) {
                    this.normalMap = resource;
                }.bind(this));
            } else {
                this.normalMap = null;
            }
        },

        _loadAsset: function (assetId, callback) {
            var asset = (assetId instanceof pc.asset.Asset ? assetId : this.system.context.assets.getAssetById(assetId));
            if (!asset) {
                logERROR(pc.string.format('Trying to load particle system before asset {0} is loaded.', assetId));
                return;
            }

            // try to load the cached asset first
            var resource;
            if (asset.resource) {
                callback(asset.resource);

            } else {
                // resource is not in cache so load it dynamically
                var options = {
                    parent: this.entity.getRequest()
                };

                this.system.context.assets.load(asset, [], options).then(function (resources) {
                    callback(resources[0]);
                });
            }
        },

        onSetMesh: function (name, oldValue, newValue) {
            if (newValue) {
                if (newValue instanceof pc.asset.Asset || pc.type(newValue) === 'number') {
                    // asset
                    this._loadAsset(newValue, function (model) {
                        this._onMeshChanged(model);
                    }.bind(this));
                } else {
                    // model resource
                    this._onMeshChanged(newValue);
                }
            } else {
                // null model
                this._onMeshChanged(null);
            }
        },

        _onMeshChanged: function (mesh) {
            if (mesh) {
                if (mesh.meshInstances[0]) {
                    mesh = mesh.meshInstances[0].mesh;
                } else {
                    mesh = null;
                }
            }

            this.data.mesh = mesh;

            if (this.emitter) {
                this.emitter.mesh = mesh;
                this.emitter.resetMaterial();
                this.rebuild();
            }
        },

        onSetOneShot: function (name, oldValue, newValue) {
            if (this.emitter) {
                this.emitter[name] = newValue;
                this.emitter.resetTime();
            }
        },

        onSetSimpleProperty: function (name, oldValue, newValue) {
            if (this.emitter) {
                this.emitter[name] = newValue;
                this.emitter.resetMaterial();
            }
        },

        onSetComplexProperty: function (name, oldValue, newValue) {
            if (this.emitter) {
                this.emitter[name] = newValue;
                this.emitter.resetMaterial();
                this.rebuild();
            }
        },

        onEnable: function() {
            if (!this.emitter && !this.system._inTools) {

                // try to get a valid camera
                if (!this.data.camera) {
                    var camera = this.system.context.systems.camera.cameras[0];
                    if (camera) {
                        this.data.camera = camera.entity;
                    }
                }

                this.emitter = new pc.scene.ParticleEmitter2(this.system.context.graphicsDevice, {
                    numParticles: this.data.numParticles,
                    spawnBounds: this.data.spawnBounds,
                    wrap: this.data.wrap,
                    wrapBounds: this.data.wrapBounds,
                    lifetime: this.data.lifetime,
                    rate: this.data.rate,
                    localOffsetGraph: this.data.localOffsetGraph,
                    offsetGraph: this.data.offsetGraph,
                    angleGraph: this.data.angleGraph,
                    scaleGraph: this.data.scaleGraph,
                    colorGraph: this.data.colorGraph,
                    alphaGraph: this.data.alphaGraph,
                    localPosDivGraph: this.data.localPosDivGraph,
                    posDivGraph: this.data.posDivGraph,
                    scaleDiv: this.data.scaleDiv,
                    angleDivGraph: this.data.angleDivGraph,
                    alphaDivGraph: this.data.alphaDivGraph,
                    colorMap: this.data.colorMap,
                    normalMap: this.data.normalMap,
                    oneShot: this.data.oneShot,
                    speedDiv: this.data.speedDiv,
                    constantSpeedDiv: this.data.constantSpeedDiv,
                    sort: this.data.sort,
                    stretch: this.data.stretch,
                    lighting: this.data.lighting,
                    halfLambert: this.data.halfLambert,
                    maxEmissionTime: this.data.maxEmissionTime,
                    depthSoftening: this.data.depthSoftening,
                    camera: this.data.camera,
                    scene: this.system.context.scene,
                    mesh: this.data.mesh,
                    depthTest: this.data.depthTest,
                    gammaCorrect: this.data.gammaCorrect,
                    smoothness: this.data.smoothness
                });
                this.emitter.meshInstance.node = this.entity;

                this.psys = new pc.scene.Model();
                this.psys.graph = this.entity;
                this.psys.emitter = this.emitter;
                this.psys.meshInstances = [this.emitter.meshInstance];
                this.data.model = this.psys;
                this.emitter.psys = this.psys;

                // called after oneShot emitter is finished. As you can dynamically change oneShot parameter, it should be always initialized
				this.emitter.onFinished = function() {
					this.enabled = false;
				}.bind(this);
            }


            ParticleSystemComponent._super.onEnable.call(this);
            if (this.data.model) {
                if (!this.system.context.scene.containsModel(this.data.model)) {
                    if (this.emitter.colorMap) {
                        this.system.context.scene.addModel(this.data.model);
                    }
                }
            }
        },

        onDisable: function() {
            ParticleSystemComponent._super.onDisable.call(this);
            if (this.data.model) {
                if (this.system.context.scene.containsModel(this.data.model)) {
                    this.system.context.scene.removeModel(this.data.model);
                }
            }
        },

        reset: function() {
            this.emitter.reset();
        },

        rebuild: function() {
            var enabled = this.enabled;
            this.enabled = false;
            this.emitter.rebuild(); // worst case: required to rebuild buffers/shaders
            this.emitter.meshInstance.node = this.entity;
            this.data.model.meshInstances = [this.emitter.meshInstance];
            this.enabled = enabled;
        },
    });


    return {
        ParticleSystemComponent: ParticleSystemComponent
    };
}());

{'fraction_non_alphanumeric': 0.1021443139848961, 'fraction_numerical': 0.0006063612810760157, 'mean_word_length': 1.391195465928562, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, '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': '3436637', 'n_tokens_mistral': 4891, 'n_tokens_neox': 4530, 'n_words': 844}