/// <summary> /// </summary> protected static ushort GetIndexDescending(float value, LodValueList materialLodValueList) { ushort index = 0; for (var i = 0; i < materialLodValueList.Count; i++, index++) { if (materialLodValueList[i] < value) { return((ushort)(index - 1)); } } return((ushort)(materialLodValueList.Count - 1)); }
public Region(StaticGeometry parent, string name, SceneManager mgr, UInt32 regionID, Vector3 center) : base(name) { MovableType = "StaticGeometry"; this.parent = parent; this.sceneMgr = mgr; this.regionID = regionID; this.center = center; this.queuedSubMeshes = new List <QueuedSubMesh>(); this.lodValues = new LodValueList(); this.aabb = new AxisAlignedBox(); this.lodBucketList = new List <LODBucket>(); this.shadowRenderables = new ShadowRenderableList(); }
public void GetIndexDescendingTest() { var materialLodUsageList = new LodValueList() { new Real(3.0f), new Real(2.0f), new Real(1.0f), new Real(0.0f) }; var lodStrategy = new LodStategyDescending(); for (int expected = 0; expected < materialLodUsageList.Count; expected++) { int actual = lodStrategy.GetIndex(3.0f - expected, materialLodUsageList); Assert.AreEqual(expected, actual); } }
/// <summary> /// Implementation of isSorted suitable for descending values. /// </summary> /// <param name="values"></param> /// <returns></returns> protected static bool IsSortedDescending(LodValueList values) { for (var i = 0; i < values.Count; i++) { float prev = values[i]; if (i + 1 < values.Count) { if (values[i + 1] > prev) { return(false); } } } return(true); }
public void GenerateLodLevels( LodValueList lodValues, ProgressiveMesh.VertexReductionQuota reductionMethod, Real reductionValue ) { RemoveLodLevels(); LogManager.Instance.Write( "Generating {0} lower LODs for mesh {1}.", lodValues.Count, Name ); foreach ( var subMesh in this._subMeshList ) { // check if triangles are present if ( subMesh.IndexData.indexCount > 0 ) { // Set up data for reduction var vertexData = subMesh.useSharedVertices ? this._sharedVertexData : subMesh.vertexData; var pm = new ProgressiveMesh( vertexData, subMesh.indexData ); pm.Build( (ushort)lodValues.Count, subMesh.lodFaceList, reductionMethod, reductionValue ); } else { // create empty index data for each lod for ( var i = 0; i < lodValues.Count; ++i ) { subMesh.LodFaceList.Add( new IndexData() ); } } } // Iterate over the lods and record usage foreach ( var value in lodValues ) { // Record usage var lod = new MeshLodUsage(); lod.UserValue = value; lod.Value = this._lodStrategy.TransformUserValue( value ); lod.EdgeData = null; lod.ManualMesh = null; this.meshLodUsageList.Add( lod ); } }
/// <summary> /// /// </summary> /// <param name="terrain"></param> /// <returns></returns> public override Material Generate( Terrain terrain ) { // re-use old material if exists Material mat = terrain._Material; if ( mat == null ) { MaterialManager matMgr = MaterialManager.Instance; // it's important that the names are deterministic for a given terrain, so // use the terrain pointer as an ID+ string matName = terrain.MaterialName; mat = (Material)matMgr.GetByName( matName ); if ( mat == null ) { mat = (Material)matMgr.Create( matName, ResourceGroupManager.DefaultResourceGroupName ); } } // clear everything mat.RemoveAllTechniques(); AddTechnique( mat, terrain, TechniqueType.HighLod ); //LOD if ( this.mCompositeMapEnabled ) { AddTechnique( mat, terrain, TechniqueType.LowLod ); var lodValues = new LodValueList(); lodValues.Add( 3000 ); //TerrainGlobalOptions.CompositeMapDistance); mat.SetLodLevels( lodValues ); Technique lowLodTechnique = mat.GetTechnique( 1 ); lowLodTechnique.LodIndex = 1; } UpdateParams( mat, terrain ); //mat.Compile(true); return mat; }
public override bool IsSorted(LodValueList values) { // Check if values are sorted descending return(IsSortedDescending(values)); }
public override bool IsSorted(LodValueList values) { return(IsSortedAscending(values)); }
public Region( StaticGeometry parent, string name, SceneManager mgr, UInt32 regionID, Vector3 center ) : base( name ) { MovableType = "StaticGeometry"; this.parent = parent; this.sceneMgr = mgr; this.regionID = regionID; this.center = center; this.queuedSubMeshes = new List<QueuedSubMesh>(); this.lodValues = new LodValueList(); this.aabb = new AxisAlignedBox(); this.lodBucketList = new List<LODBucket>(); this.shadowRenderables = new ShadowRenderableList(); }
public abstract bool IsSorted(LodValueList values);
public override ushort GetIndex(Real value, LodValueList materialLodValueList) { return(GetIndexAscending(value, materialLodValueList)); }
protected static bool ParseLodDistances( string parameters, MaterialScriptContext context ) { context.material.LodStrategy = LodStrategyManager.Instance.GetStrategy( DistanceLodStrategy.StrategyName ); string[] values = parameters.Split( new char[] { ' ', '\t' } ); LodValueList lodDistances = new LodValueList(); for ( int i = 0; i < values.Length; i++ ) { lodDistances.Add( StringConverter.ParseFloat( values[ i ] ) ); } context.material.SetLodLevels( lodDistances ); return false; }
public override ushort GetIndex(Real value, LodValueList materialLodValueList) { // Values are descending return(GetIndexDescending(value, materialLodValueList)); }
/// <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(); }
public override ushort GetIndex( Real value, LodValueList materialLodValueList ) { // Values are descending return GetIndexDescending( value, materialLodValueList ); }
public override bool IsSorted(LodValueList values) { throw new NotImplementedException(); }
public void GetIndexDescendingTest() { var materialLodUsageList = new LodValueList() { new Real( 3.0f ), new Real( 2.0f ), new Real( 1.0f ), new Real( 0.0f ) }; var lodStrategy = new LodStategyDescending(); for ( int expected = 0; expected < materialLodUsageList.Count; expected++ ) { int actual = lodStrategy.GetIndex( 3.0f - expected, materialLodUsageList ); Assert.AreEqual( expected, actual ); } }
public override ushort GetIndex(Axiom.Math.Real value, LodValueList materialLodValueList) { return(GetIndexDescending(value, materialLodValueList)); }
public override ushort GetIndex( Axiom.Math.Real value, LodValueList materialLodValueList ) { return GetIndexDescending( value, materialLodValueList ); }
public override bool IsSorted( LodValueList values ) { throw new NotImplementedException(); }
public override bool IsSorted( LodValueList values ) { // Check if values are sorted descending return IsSortedDescending( values ); }
public abstract ushort GetIndex(Real value, LodValueList materialLodValueList);
/// <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(); }
/// <summary> /// Sets the distance at which level-of-detail (LOD) levels come into effect. /// </summary> /// <remarks> /// You should only use this if you have assigned LOD indexes to the <see cref="Technique"/> /// instances attached to this <see cref="Material"/>. If you have done so, you should call this /// method to determine the distance at which the low levels of detail kick in. /// The decision about what distance is actually used is a combination of this /// and the LOD bias applied to both the current <see cref="Camera"/> and the current Entity. /// </remarks> /// <param name="lodDistanceList"> /// A list of floats which indicate the distance at which to /// switch to lower details. They are listed in LOD index order, starting at index /// 1 (ie the first level down from the highest level 0, which automatically applies /// from a distance of 0). /// </param> /// <ogre name="setLoadLevels" /> public void SetLodLevels( LodValueList lodDistanceList ) { // clear and add the 0 distance entry this._lodValues.Clear(); this.UserLodValues.Clear(); this.UserLodValues.Add( float.NaN ); this._lodValues.Add( LodStrategy.BaseValue ); foreach ( Real lodValue in lodDistanceList ) { this.UserLodValues.Add( lodValue ); if ( LodStrategy != null ) { this._lodValues.Add( LodStrategy.TransformUserValue( lodValue ) ); } } }