Beispiel #1
0
			public void Assign( QueuedSubMesh qsm )
			{
				this.queuedSubMeshes.Add( qsm );

				// update lod distances
				var mesh = qsm.submesh.Parent;
				var lodStrategy = mesh.LodStrategy;
				if ( this.lodStrategy == null )
				{
					this.lodStrategy = lodStrategy;
					// First LOD mandatory, and always from base lod value
					this.lodValues.Add( this.lodStrategy.BaseValue );
				}
				else
				{
					if ( this.lodStrategy != lodStrategy )
					{
						throw new AxiomException( "Lod strategies do not match." );
					}
				}

				var lodLevels = mesh.LodLevelCount;
				if ( qsm.geometryLodList.Count != lodLevels )
				{
					var msg = string.Format( "QueuedSubMesh '{0}' lod count of {1} does not match parent count of {2}",
					                         qsm.submesh.Name, qsm.geometryLodList.Count, lodLevels );
					throw new AxiomException( msg );
				}

				while ( this.lodValues.Count < lodLevels )
				{
					this.lodValues.Add( 0.0f );
				}
				// Make sure LOD levels are max of all at the requested level
				for ( ushort lod = 1; lod < lodLevels; ++lod )
				{
					var meshLod = qsm.submesh.Parent.GetLodLevel( lod );
					this.lodValues[ lod ] = Utility.Max( (float)this.lodValues[ lod ], meshLod.Value );
				}

				// update bounds
				// Transform world bounds relative to our center
				var localBounds = new AxisAlignedBox( qsm.worldBounds.Minimum - this.center, qsm.worldBounds.Maximum - this.center );
				this.aabb.Merge( localBounds );
				foreach ( var corner in localBounds.Corners )
				{
					this.boundingRadius = Utility.Max( this.boundingRadius, corner.Length );
				}
			}
Beispiel #2
0
            /// <see cref="Translator.Translate"/>
            public override void Translate(ScriptCompiler compiler, AbstractNode node)
            {
                var obj = (ObjectAbstractNode)node;

                if (obj != null)
                {
                    if (string.IsNullOrEmpty(obj.Name))
                    {
                        compiler.AddError(CompileErrorCode.ObjectNameExpected, obj.File, obj.Line);
                    }
                }
                else
                {
                    compiler.AddError(CompileErrorCode.ObjectNameExpected, node.File, node.Line);
                    return;
                }

                // Create a material with the given name
                object mat;
                ScriptCompilerEvent evt = new CreateMaterialScriptCompilerEvent(node.File, obj.Name, compiler.ResourceGroup);
                var processed           = compiler._fireEvent(ref evt, out mat);

                if (!processed)
                {
                    //TODO
                    // The original translated implementation of this code block was simply the following:
                    // _material = (Material)MaterialManager.Instance.Create( obj.Name, compiler.ResourceGroup );
                    // but sometimes it generates an exception due to a duplicate resource.
                    // In order to avoid the above mentioned exception, the implementation was changed, but
                    // it need to be checked when ResourceManager._add will be updated to the latest version

                    var checkForExistingMat = (Material)MaterialManager.Instance.GetByName(obj.Name);

                    if (checkForExistingMat == null)
                    {
                        this._material = (Material)MaterialManager.Instance.Create(obj.Name, compiler.ResourceGroup);
                    }
                    else
                    {
                        this._material = checkForExistingMat;
                    }
                }
                else
                {
                    this._material = (Material)mat;

                    if (this._material == null)
                    {
                        compiler.AddError(CompileErrorCode.ObjectAllocationError, obj.File, obj.Line,
                                          "failed to find or create material \"" + obj.Name + "\"");
                    }
                }

                this._material.RemoveAllTechniques();
                obj.Context           = this._material;
                this._material.Origin = obj.File;

                foreach (var i in obj.Children)
                {
                    if (i is PropertyAbstractNode)
                    {
                        var prop = (PropertyAbstractNode)i;

                        switch ((Keywords)prop.Id)
                        {
                            #region ID_LOD_VALUES

                        case Keywords.ID_LOD_VALUES:
                        {
                            var lods = new LodValueList();
                            foreach (var j in prop.Values)
                            {
                                Real v = 0;
                                if (getReal(j, out v))
                                {
                                    lods.Add(v);
                                }
                                else
                                {
                                    compiler.AddError(CompileErrorCode.NumberExpected, prop.File, prop.Line,
                                                      "lod_values expects only numbers as arguments");
                                }
                            }
                            this._material.SetLodLevels(lods);
                        }
                        break;

                            #endregion ID_LOD_VALUES

                            #region ID_LOD_DISTANCES

                        case Keywords.ID_LOD_DISTANCES:
                        {
                            // Set strategy to distance strategy
                            LodStrategy strategy = DistanceLodStrategy.Instance;
                            this._material.LodStrategy = strategy;

                            // Real in lod distances
                            var lods = new LodValueList();
                            foreach (var j in prop.Values)
                            {
                                Real v = 0;
                                if (getReal(j, out v))
                                {
                                    lods.Add(v);
                                }
                                else
                                {
                                    compiler.AddError(CompileErrorCode.NumberExpected, prop.File, prop.Line,
                                                      "lod_values expects only numbers as arguments");
                                }
                            }
                            this._material.SetLodLevels(lods);
                        }
                        break;

                            #endregion ID_LOD_DISTANCES

                            #region ID_LOD_STRATEGY

                        case Keywords.ID_LOD_STRATEGY:
                            if (prop.Values.Count == 0)
                            {
                                compiler.AddError(CompileErrorCode.StringExpected, prop.File, prop.Line);
                            }
                            else if (prop.Values.Count > 1)
                            {
                                compiler.AddError(CompileErrorCode.FewerParametersExpected, prop.File, prop.Line,
                                                  "lod_strategy only supports 1 argument");
                            }
                            else
                            {
                                var strategyName = string.Empty;
                                var result       = getString(prop.Values[0], out strategyName);
                                if (result)
                                {
                                    var strategy = LodStrategyManager.Instance.GetStrategy(strategyName);

                                    result = strategy != null;

                                    if (result)
                                    {
                                        this._material.LodStrategy = strategy;
                                    }
                                }

                                if (!result)
                                {
                                    compiler.AddError(CompileErrorCode.InvalidParameters, prop.File, prop.Line,
                                                      "lod_strategy argument must be a valid lod strategy");
                                }
                            }
                            break;

                            #endregion ID_LOD_STRATEGY

                            #region ID_RECEIVE_SHADOWS

                        case Keywords.ID_RECEIVE_SHADOWS:
                            if (prop.Values.Count == 0)
                            {
                                compiler.AddError(CompileErrorCode.StringExpected, prop.File, prop.Line);
                            }
                            else if (prop.Values.Count > 1)
                            {
                                compiler.AddError(CompileErrorCode.FewerParametersExpected, prop.File, prop.Line,
                                                  "receive_shadows only supports 1 argument");
                            }
                            else
                            {
                                var val = true;
                                if (getBoolean(prop.Values[0], out val))
                                {
                                    this._material.ReceiveShadows = val;
                                }
                                else
                                {
                                    compiler.AddError(CompileErrorCode.InvalidParameters, prop.File, prop.Line,
                                                      "receive_shadows argument must be \"true\", \"false\", \"yes\", \"no\", \"on\", or \"off\"");
                                }
                            }
                            break;

                            #endregion ID_RECEIVE_SHADOWS

                            #region ID_TRANSPARENCY_CASTS_SHADOWS

                        case Keywords.ID_TRANSPARENCY_CASTS_SHADOWS:
                            if (prop.Values.Count == 0)
                            {
                                compiler.AddError(CompileErrorCode.StringExpected, prop.File, prop.Line);
                            }
                            else if (prop.Values.Count > 1)
                            {
                                compiler.AddError(CompileErrorCode.FewerParametersExpected, prop.File, prop.Line,
                                                  "transparency_casts_shadows only supports 1 argument");
                            }
                            else
                            {
                                var val = true;
                                if (getBoolean(prop.Values[0], out val))
                                {
                                    this._material.TransparencyCastsShadows = val;
                                }
                                else
                                {
                                    compiler.AddError(CompileErrorCode.InvalidParameters, prop.File, prop.Line,
                                                      "transparency_casts_shadows argument must be \"true\", \"false\", \"yes\", \"no\", \"on\", or \"off\"");
                                }
                            }
                            break;

                            #endregion ID_TRANSPARENCY_CASTS_SHADOWS

                            #region ID_SET_TEXTURE_ALIAS

                        case Keywords.ID_SET_TEXTURE_ALIAS:
                            if (prop.Values.Count == 0)
                            {
                                compiler.AddError(CompileErrorCode.StringExpected, prop.File, prop.Line);
                            }
                            else if (prop.Values.Count > 3)
                            {
                                compiler.AddError(CompileErrorCode.FewerParametersExpected, prop.File, prop.Line);
                            }
                            else
                            {
                                AbstractNode i0 = getNodeAt(prop.Values, 0), i1 = getNodeAt(prop.Values, 1);
                                String       name, value;
                                if (getString(i0, out name) && getString(i1, out value))
                                {
                                    this._textureAliases.Add(name, value);
                                }
                                else
                                {
                                    compiler.AddError(CompileErrorCode.InvalidParameters, prop.File, prop.Line,
                                                      "set_texture_alias must have 2 string argument");
                                }
                            }
                            break;

                            #endregion ID_SET_TEXTURE_ALIAS

                        default:
                            compiler.AddError(CompileErrorCode.UnexpectedToken, prop.File, prop.Line,
                                              "token \"" + prop.Name + "\" is not recognized");
                            break;
                        } //end of switch statement
                    }
                    else if (i is ObjectAbstractNode)
                    {
                        processNode(compiler, i);
                    }
                }

                // Apply the texture aliases
                ScriptCompilerEvent locEvt = new PreApplyTextureAliasesScriptCompilerEvent(this._material, ref this._textureAliases);
                compiler._fireEvent(ref locEvt);

                this._material.ApplyTextureAliases(this._textureAliases);
                this._textureAliases.Clear();
            }