public static void TranslateProgramParameters( ScriptCompiler compiler, /*it should be GpuProgramParametersShared*/ GpuProgramParameters parameters, ObjectAbstractNode obj )
{
int animParametricsCount = 0;
foreach ( AbstractNode i in obj.Children )
{
if ( i is PropertyAbstractNode )
{
PropertyAbstractNode prop = (PropertyAbstractNode)i;
LogManager.Instance.Write("TranslateProgramParameters {0}", (Keywords)prop.Id);
switch ( (Keywords)prop.Id )
{
#region ID_SHARED_PARAMS_REF
case Keywords.ID_SHARED_PARAMS_REF:
{
if ( prop.Values.Count != 1 )
{
compiler.AddError( CompileErrorCode.InvalidParameters, prop.File, prop.Line,
"shared_params_ref requires a single parameter" );
continue;
}
AbstractNode i0 = getNodeAt( prop.Values, 0 );
if ( !( i0 is AtomAbstractNode ) )
{
compiler.AddError( CompileErrorCode.InvalidParameters, prop.File, prop.Line,
"shared parameter set name expected" );
continue;
}
AtomAbstractNode atom0 = (AtomAbstractNode)i0;
throw new NotImplementedException();
#if UNREACHABLE_CODE
try
{
//TODO
//parameters->addSharedParameters(atom0->value);
}
catch ( AxiomException e )
{
compiler.AddError( CompileErrorCode.InvalidParameters, prop.File, prop.Line, e.Message );
}
}
break;
#else
}
#endif
#endregion ID_SHARED_PARAMS_REF
#region ID_PARAM_INDEXED || ID_PARAM_NAMED
case Keywords.ID_PARAM_INDEXED:
case Keywords.ID_PARAM_NAMED:
{
if ( prop.Values.Count >= 3 )
{
bool named = ( prop.Id == (uint)Keywords.ID_PARAM_NAMED );
AbstractNode i0 = getNodeAt( prop.Values, 0 ), i1 = getNodeAt( prop.Values, 1 ),
k = getNodeAt( prop.Values, 2 );
if ( !(i0 is AtomAbstractNode) || !(i1 is AtomAbstractNode) )
{
compiler.AddError( CompileErrorCode.InvalidParameters, prop.File, prop.Line,
"name or index and parameter type expected" );
return;
}
AtomAbstractNode atom0 = (AtomAbstractNode)i0, atom1 = (AtomAbstractNode)i1;
if ( !named && !atom0.IsNumber )
{
compiler.AddError( CompileErrorCode.NumberExpected, prop.File, prop.Line,
"parameter index expected" );
return;
}
string name = string.Empty;
int index = 0;
// Assign the name/index
if ( named )
name = atom0.Value;
else
index = (int)atom0.Number;
// Determine the type
if ( atom1.Value == "matrix4x4" )
{
Matrix4 m;
if ( getMatrix4( prop.Values, 2, out m ) )
{
try
{
if ( named )
parameters.SetNamedConstant( name, m );
else
parameters.SetConstant( index, m );
}
catch
{
compiler.AddError( CompileErrorCode.InvalidParameters, prop.File, prop.Line,
"setting matrix4x4 parameter failed" );
}
}
else
{
compiler.AddError( CompileErrorCode.NumberExpected, prop.File, prop.Line,
"incorrect matrix4x4 declaration" );
}
}
else
{
// Find the number of parameters
var isValid = true;
GpuProgramParameters.ElementType type = GpuProgramParameters.ElementType.Real;
int count = 0;
if ( atom1.Value.Contains( "float" ) )
{
type = GpuProgramParameters.ElementType.Real;
if ( atom1.Value.Length >= 6 )
count = int.Parse( atom1.Value.Substring( 5 ) );
else
{
count = 1;
}
}
else if ( atom1.Value.Contains( "int" ) )
{
type = GpuProgramParameters.ElementType.Int;
if ( atom1.Value.Length >= 4 )
count = int.Parse( atom1.Value.Substring( 3 ) );
else
{
count = 1;
}
}
else
{
compiler.AddError( CompileErrorCode.InvalidParameters, prop.File, prop.Line,
"incorrect type specified; only variants of int and float allowed" );
isValid = false;
}
if ( isValid )
{
// First, clear out any offending auto constants
if ( named )
{
parameters.ClearNamedAutoConstant(name);
}
else
{
parameters.ClearAutoConstant(index);
}
int roundedCount = count % 4 != 0 ? count + 4 - ( count % 4 ) : count;
if ( type == GpuProgramParameters.ElementType.Int )
{
int[] vals = new int[ roundedCount ];
if ( getInts( prop.Values, 2, out vals, roundedCount ) )
{
try
{
if ( named )
{
parameters.SetNamedConstant(name, vals, count, 1);
}
else
{
parameters.SetConstant(index , vals, roundedCount/4);
}
}
catch
{
compiler.AddError( CompileErrorCode.InvalidParameters, prop.File, prop.Line,
"setting of constant failed" );
}
}
else
{
compiler.AddError( CompileErrorCode.NumberExpected, prop.File, prop.Line,
"incorrect integer constant declaration" );
}
}
else
{
float[] vals = new float[ roundedCount ];
if ( getFloats( prop.Values, 2, out vals, roundedCount ) )
{
try
{
if ( named )
{
parameters.SetNamedConstant(name, vals, count, 1);
}
else
{
parameters.SetConstant(index , vals, roundedCount/4);
}
}
catch
{
compiler.AddError( CompileErrorCode.InvalidParameters, prop.File, prop.Line,
"setting of constant failed" );
}
}
else
{
compiler.AddError( CompileErrorCode.NumberExpected, prop.File, prop.Line,
"incorrect float constant declaration" );
}
}
}
}
}
else
{
compiler.AddError( CompileErrorCode.InvalidParameters, prop.File, prop.Line,
"param_named and param_indexed properties requires at least 3 arguments" );
}
}
break;
#endregion ID_PARAM_INDEXED || ID_PARAM_NAMED
#region ID_PARAM_INDEXED_AUTO || ID_PARAM_NAMED_AUTO
case Keywords.ID_PARAM_INDEXED_AUTO:
case Keywords.ID_PARAM_NAMED_AUTO:
{
bool named = ( prop.Id == (uint)Keywords.ID_PARAM_NAMED_AUTO );
string name = string.Empty;
int index = 0;
if ( prop.Values.Count >= 2 )
{
AbstractNode i0 = getNodeAt( prop.Values, 0 ),
i1 = getNodeAt( prop.Values, 1 ), i2 = getNodeAt( prop.Values, 2 ), i3 = getNodeAt( prop.Values, 3 );
if ( !(i0 is AtomAbstractNode) || !(i1 is AtomAbstractNode) )
{
compiler.AddError( CompileErrorCode.InvalidParameters, prop.File, prop.Line,
"name or index and auto constant type expected" );
return;
}
AtomAbstractNode atom0 = (AtomAbstractNode)i0, atom1 = (AtomAbstractNode)i1;
if ( !named && !atom0.IsNumber )
{
compiler.AddError( CompileErrorCode.NumberExpected, prop.File, prop.Line,
"parameter index expected" );
return;
}
if ( named )
name = atom0.Value;
else
index = int.Parse( atom0.Value );
// Look up the auto constant
atom1.Value = atom1.Value.ToLower();
GpuProgramParameters.AutoConstantDefinition def;
bool defFound = GpuProgramParameters.GetAutoConstantDefinition( atom1.Value, out def );
if ( defFound )
{
switch ( def.DataType )
{
#region None
case GpuProgramParameters.AutoConstantDataType.None:
// Set the auto constant
try
{
if ( named )
parameters.SetNamedAutoConstant( name, def.AutoConstantType );
else
parameters.SetAutoConstant( index, def.AutoConstantType );
}
catch
{
compiler.AddError( CompileErrorCode.InvalidParameters, prop.File, prop.Line,
"setting of constant failed" );
}
break;
#endregion None
#region Int
case GpuProgramParameters.AutoConstantDataType.Int:
if ( def.AutoConstantType == GpuProgramParameters.AutoConstantType.AnimationParametric )
{
try
{
if ( named )
parameters.SetNamedAutoConstant( name, def.AutoConstantType, animParametricsCount++ );
else
parameters.SetAutoConstant( index, def.AutoConstantType, animParametricsCount++ );
}
catch
{
compiler.AddError( CompileErrorCode.InvalidParameters, prop.File, prop.Line,
"setting of constant failed" );
}
}
else
{
// Only certain texture projection auto params will assume 0
// Otherwise we will expect that 3rd parameter
if ( i2 == null )
{
if ( def.AutoConstantType == GpuProgramParameters.AutoConstantType.TextureViewProjMatrix ||
def.AutoConstantType == GpuProgramParameters.AutoConstantType.TextureWorldViewProjMatrix ||
def.AutoConstantType == GpuProgramParameters.AutoConstantType.SpotLightViewProjMatrix ||
def.AutoConstantType == GpuProgramParameters.AutoConstantType.SpotLightWorldViewProjMatrix )
{
try
{
if ( named )
parameters.SetNamedAutoConstant( name, def.AutoConstantType, 0 );
else
parameters.SetAutoConstant( index, def.AutoConstantType, 0 );
}
catch
{
compiler.AddError( CompileErrorCode.InvalidParameters, prop.File, prop.Line,
"setting of constant failed" );
}
}
else
{
compiler.AddError( CompileErrorCode.NumberExpected, prop.File, prop.Line,
"extra parameters required by constant definition " + atom1.Value );
}
}
else
{
bool success = false;
int extraInfo = 0;
if ( i3 == null )
{ // Handle only one extra value
if ( getInt( i2, out extraInfo ) )
{
success = true;
}
}
else
{ // Handle two extra values
int extraInfo1 = 0, extraInfo2 = 0;
if ( getInt( i2, out extraInfo1 ) && getInt( i3, out extraInfo2 ) )
{
extraInfo = extraInfo1 | ( extraInfo2 << 16 );
success = true;
}
}
if ( success )
{
try
{
if ( named )
parameters.SetNamedAutoConstant( name, def.AutoConstantType, extraInfo );
else
parameters.SetAutoConstant( index, def.AutoConstantType, extraInfo );
}
catch
{
compiler.AddError( CompileErrorCode.InvalidParameters, prop.File, prop.Line,
"setting of constant failed" );
}
}
else
{
compiler.AddError( CompileErrorCode.InvalidParameters, prop.File, prop.Line,
"invalid auto constant extra info parameter" );
}
}
}
break;
#endregion Int
#region Real
case GpuProgramParameters.AutoConstantDataType.Real:
if ( def.AutoConstantType == GpuProgramParameters.AutoConstantType.Time ||
def.AutoConstantType == GpuProgramParameters.AutoConstantType.FrameTime )
{
Real f = 1.0f;
if ( i2 != null )
getReal( i2, out f );
try
{
if ( named )
{
parameters.SetNamedAutoConstantReal(name, def.AutoConstantType, f);
}
else
parameters.SetAutoConstantReal( index, def.AutoConstantType, f );
}
catch
{
compiler.AddError( CompileErrorCode.InvalidParameters, prop.File, prop.Line,
"setting of constant failed" );
}
}
else
{
if ( i2 != null )
{
Real extraInfo = 0.0f;
if ( getReal( i2, out extraInfo ) )
{
try
{
if ( named )
{
parameters.SetNamedAutoConstantReal(name, def.AutoConstantType, extraInfo);
}
else
parameters.SetAutoConstantReal( index, def.AutoConstantType, extraInfo );
}
catch
{
compiler.AddError( CompileErrorCode.InvalidParameters, prop.File, prop.Line,
"setting of constant failed" );
}
}
else
{
compiler.AddError( CompileErrorCode.InvalidParameters, prop.File, prop.Line,
"incorrect float argument definition in extra parameters" );
}
}
else
{
compiler.AddError( CompileErrorCode.NumberExpected, prop.File, prop.Line,
"extra parameters required by constant definition " + atom1.Value );
}
}
break;
#endregion Real
}
}
else
{
compiler.AddError( CompileErrorCode.InvalidParameters, prop.File, prop.Line );
}
}
else
{
compiler.AddError( CompileErrorCode.InvalidParameters, prop.File, prop.Line );
}
}
break;