public PropertyTable(Element element, PropertyTable templateProps) { this.templateProps = templateProps; this.element = element; Scope scope = Parser.GetRequiredScope(element); foreach(var i in scope.Elements) { if (i.Key != "P") { Console.Error.WriteLine("expected only P elements in property table"); continue; } foreach (var j in i.Value) { string name = PeekPropertyName(j); if (name.Length == 0) { Console.Error.WriteLine("could not read property name"); continue; } if (lazyProps.ContainsKey(name)) { Console.Error.WriteLine("duplicate property name, will hide previous value: " + name); continue; } lazyProps[name] = j; } } }
public NodeAttribute(ulong id, Element element, Document doc, string name) : base(id, element, name) { var sc = Parser.GetRequiredScope(element); var classname = Parser.ParseTokenAsString(Parser.GetRequiredToken(element, 2)); var isNullOrLimb = (classname == "Null") || (classname == "LimbNode"); props = DocumentUtil.GetPropertyTable(doc, "NodeAttribute.Fbx" + classname, element, sc, isNullOrLimb); }
/// <summary> /// Represents a FBX animation layer (i.e. a list of node animations) /// </summary> public AnimationLayer(ulong id, Element element, string name, Document doc) : base(id, element, name) { this.doc = doc; var sc = Parser.GetRequiredScope(element); // note: the props table here bears little importance and is usually absent this.props = DocumentUtil.GetPropertyTable(doc, "AnimationLayer.FbxAnimLayer", element, sc, true); }
public Texture(ulong id, Element element, Document doc, string name) : base(id, element, name) { uvScaling = new Vector2(1, 1); var sc = Parser.GetRequiredScope(element); var Type = sc["Type"]; var FileName = sc["FileName"]; var RelativeFilename = sc["RelativeFilename"]; var ModelUVTranslation = sc["ModelUVTranslation"]; var ModelUVScaling = sc["ModelUVScaling"]; var Texture_Alpha_Source = sc["Texture_Alpha_Source"]; var Cropping = sc["Cropping"]; if (Type != null) { type = Parser.ParseTokenAsString(Parser.GetRequiredToken(Type, 0)); } if (FileName != null) { fileName = Parser.ParseTokenAsString(Parser.GetRequiredToken(FileName, 0)); } if (RelativeFilename != null) { relativeFileName = Parser.ParseTokenAsString(Parser.GetRequiredToken(RelativeFilename, 0)); } if (ModelUVTranslation != null) { uvTrans = new Vector2(Parser.ParseTokenAsFloat(Parser.GetRequiredToken(ModelUVTranslation, 0)), Parser.ParseTokenAsFloat(Parser.GetRequiredToken(ModelUVTranslation, 1))); } if (ModelUVScaling != null) { uvTrans = new Vector2(Parser.ParseTokenAsFloat(Parser.GetRequiredToken(ModelUVScaling, 0)), Parser.ParseTokenAsFloat(Parser.GetRequiredToken(ModelUVScaling, 1))); } if (Cropping != null) { uint i1 = (uint)Parser.ParseTokenAsInt(Parser.GetRequiredToken(Cropping, 0)); uint i2 = (uint)Parser.ParseTokenAsInt(Parser.GetRequiredToken(Cropping, 1)); uint i3 = (uint)Parser.ParseTokenAsInt(Parser.GetRequiredToken(Cropping, 2)); uint i4 = (uint)Parser.ParseTokenAsInt(Parser.GetRequiredToken(Cropping, 3)); crop = new Tuple<uint, uint, uint, uint>(i1, i2, i3, i4); } else { crop = new Tuple<uint, uint, uint, uint>(0, 0, 0, 0); } if (Texture_Alpha_Source != null) { alphaSource = Parser.ParseTokenAsString(Parser.GetRequiredToken(Texture_Alpha_Source, 0)); } props = DocumentUtil.GetPropertyTable(doc, "Texture.FbxFileTexture", element, sc); }
public AnimationStack(ulong id, Element element, string name, Document doc) : base(id, element, name) { var sc = Parser.GetRequiredScope(element); // note: we don't currently use any of these properties so we shouldn't bother if it is missing props = DocumentUtil.GetPropertyTable(doc, "AnimationStack.FbxAnimStack", element, sc, true); // resolve attached animation layers var conns = doc.GetConnectionsByDestinationSequenced(ID, "AnimationLayer"); layers = new List<AnimationLayer>(conns.Count); foreach (var con in conns) { // link should not go to a property if (!string.IsNullOrEmpty(con.PropertyName)) { continue; } var ob = con.SourceObject; if (ob == null) { DocumentUtil.DOMWarning("failed to read source object for AnimationLayer->AnimationStack link, ignoring", element); continue; } var anim = ob as AnimationLayer; if (anim == null) { DocumentUtil.DOMWarning("source object for ->AnimationStack link is not an AnimationLayer", element); continue; } layers.Add(anim); } LocalStart = new SimpleProperty<long>(props, "LocalStart", 0); LocalStop = new SimpleProperty<long>(props, "LocalStop", 0); ReferenceStart = new SimpleProperty<long>(props, "ReferenceStart", 0); ReferenceStop = new SimpleProperty<long>(props, "ReferenceStop", 0); }
public FileGlobalSettings(Document doc, PropertyTable prop) { this.doc = doc; this.props = prop; UpAxis = new SimpleProperty<int>(prop, "UpAxis", 1); UnAxisSign = new SimpleProperty<int>(prop, "UnAxisSign", 1); FrontAxis = new SimpleProperty<int>(prop, "FrontAxis", 2); FrontAxisSign = new SimpleProperty<int>(prop, "FrontAxisSign", 1); CoordAxis = new SimpleProperty<int>(prop, "CoordAxis", 0); CoordAxisSign = new SimpleProperty<int>(prop, "CoordAxisSign", 0); OriginalUpAxis = new SimpleProperty<int>(prop, "OriginalUpAxis", 0); OriginalUpAxisSign = new SimpleProperty<int>(prop, "OriginalUpAxisSign", 0); UnitScaleFactor = new SimpleProperty<double>(prop, "UnitScaleFactor", 0); OriginalUnitScaleFactor = new SimpleProperty<double>(prop, "OriginalUnitScaleFactor", 0); AmbientColor = new SimpleProperty<Vector3>(prop, "AmbientColor", new Vector3(0, 0, 0)); DefaultCamera = new SimpleProperty<string>(prop, "DefaultCamera", ""); TimeMode = new SimpleProperty<FrameRate>(prop, "TimeMode", FrameRate.FrameRate_DEFAULT); TimeSpanStart = new SimpleProperty<ulong>(prop, "TimeSpanStart", 0); TimeSpanStop = new SimpleProperty<ulong>(prop, "TimeSpanStop", 0); CustomFrameRate = new SimpleProperty<float>(prop, "CustomFrameRate", -1f); }
public Model(ulong id, Element element, Document doc, string name) : base(id, element, name) { shading = "Y"; var sc = Parser.GetRequiredScope(element); var Shading = sc["Shading"]; var Culling = sc["Culling"]; if (Shading != null) { shading = Parser.GetRequiredToken(Shading, 0).StringContents; } if (Culling != null) { culling = Parser.ParseTokenAsString(Parser.GetRequiredToken(Culling, 0)); } props = DocumentUtil.GetPropertyTable(doc, "Model.FbxNode", element, sc); ResolveLink(element, doc); this.QuaternionInterpolate = new SimpleProperty<int>(this.Props, "QuaternionInterpolate", 0); this.RotationOrder = new SimpleProperty<RotOrder>(this.Props, "RotationOrder", (RotOrder)0); this.RotationOffset = new SimpleProperty<Vector3>(this.Props, "RotationOffset", new Vector3()); this.RotationPivot = new SimpleProperty<Vector3>(this.Props, "RotationPivot", new Vector3()); this.ScalingOffset = new SimpleProperty<Vector3>(this.Props, "ScalingOffset", new Vector3()); this.ScalingPivot = new SimpleProperty<Vector3>(this.Props, "ScalingPivot", new Vector3()); this.TranslationActive = new SimpleProperty<bool>(this.Props, "TranslationActive", false); this.TranslationMin = new SimpleProperty<Vector3>(this.Props, "TranslationMin", new Vector3()); this.TranslationMax = new SimpleProperty<Vector3>(this.Props, "TranslationMax", new Vector3()); this.TranslationMinX = new SimpleProperty<bool>(this.Props, "TranslationMinX", false); this.TranslationMaxX = new SimpleProperty<bool>(this.Props, "TranslationMaxX", false); this.TranslationMinY = new SimpleProperty<bool>(this.Props, "TranslationMinY", false); this.TranslationMaxY = new SimpleProperty<bool>(this.Props, "TranslationMaxY", false); this.TranslationMinZ = new SimpleProperty<bool>(this.Props, "TranslationMinZ", false); this.TranslationMaxZ = new SimpleProperty<bool>(this.Props, "TranslationMaxZ", false); this.RotationOrder = new SimpleProperty<RotOrder>(this.Props, "RotationOrder", (RotOrder)0); this.RotationSpaceForLimitOnly = new SimpleProperty<bool>(this.Props, "RotationSpaceForLimitOnly", false); this.RotationStiffnessX = new SimpleProperty<float>(this.Props, "RotationStiffnessX", 0.0f); this.RotationStiffnessY = new SimpleProperty<float>(this.Props, "RotationStiffnessY", 0.0f); this.RotationStiffnessZ = new SimpleProperty<float>(this.Props, "RotationStiffnessZ", 0.0f); this.AxisLen = new SimpleProperty<float>(this.Props, "AxisLen", 0.0f); this.PreRotation = new SimpleProperty<Vector3>(this.Props, "PreRotation", new Vector3()); this.PostRotation = new SimpleProperty<Vector3>(this.Props, "PostRotation", new Vector3()); this.RotationActive = new SimpleProperty<bool>(this.Props, "RotationActive", false); this.RotationMin = new SimpleProperty<Vector3>(this.Props, "RotationMin", new Vector3()); this.RotationMax = new SimpleProperty<Vector3>(this.Props, "RotationMax", new Vector3()); this.RotationMinX = new SimpleProperty<bool>(this.Props, "RotationMinX", false); this.RotationMaxX = new SimpleProperty<bool>(this.Props, "RotationMaxX", false); this.RotationMinY = new SimpleProperty<bool>(this.Props, "RotationMinY", false); this.RotationMaxY = new SimpleProperty<bool>(this.Props, "RotationMaxY", false); this.RotationMinZ = new SimpleProperty<bool>(this.Props, "RotationMinZ", false); this.RotationMaxZ = new SimpleProperty<bool>(this.Props, "RotationMaxZ", false); this.InheritType = new SimpleProperty<TransformInheritance>(this.Props, "InheritType", (TransformInheritance)0); this.ScalingActive = new SimpleProperty<bool>(this.Props, "ScalingActive", false); this.ScalingMin = new SimpleProperty<Vector3>(this.Props, "ScalingMin", new Vector3()); this.ScalingMax = new SimpleProperty<Vector3>(this.Props, "ScalingMax", new Vector3(1.0f, 1.0f, 1.0f)); this.ScalingMinX = new SimpleProperty<bool>(this.Props, "ScalingMinX", false); this.ScalingMaxX = new SimpleProperty<bool>(this.Props, "ScalingMaxX", false); this.ScalingMinY = new SimpleProperty<bool>(this.Props, "ScalingMinY", false); this.ScalingMaxY = new SimpleProperty<bool>(this.Props, "ScalingMaxY", false); this.ScalingMinZ = new SimpleProperty<bool>(this.Props, "ScalingMinZ", false); this.ScalingMaxZ = new SimpleProperty<bool>(this.Props, "ScalingMaxZ", false); this.GeometricTranslation = new SimpleProperty<Vector3>(this.Props, "GeometricTranslation", new Vector3()); this.GeometricRotation = new SimpleProperty<Vector3>(this.Props, "GeometricRotation", new Vector3()); this.GeometricScaling = new SimpleProperty<Vector3>(this.Props, "GeometricScaling", new Vector3(1.0f, 1.0f, 1.0f)); this.MinDampRangeX = new SimpleProperty<float>(this.Props, "MinDampRangeX", 0.0f); this.MinDampRangeY = new SimpleProperty<float>(this.Props, "MinDampRangeY", 0.0f); this.MinDampRangeZ = new SimpleProperty<float>(this.Props, "MinDampRangeZ", 0.0f); this.MaxDampRangeX = new SimpleProperty<float>(this.Props, "MaxDampRangeX", 0.0f); this.MaxDampRangeY = new SimpleProperty<float>(this.Props, "MaxDampRangeY", 0.0f); this.MaxDampRangeZ = new SimpleProperty<float>(this.Props, "MaxDampRangeZ", 0.0f); this.MinDampStrengthX = new SimpleProperty<float>(this.Props, "MinDampStrengthX", 0.0f); this.MinDampStrengthY = new SimpleProperty<float>(this.Props, "MinDampStrengthY", 0.0f); this.MinDampStrengthZ = new SimpleProperty<float>(this.Props, "MinDampStrengthZ", 0.0f); this.MaxDampStrengthX = new SimpleProperty<float>(this.Props, "MaxDampStrengthX", 0.0f); this.MaxDampStrengthY = new SimpleProperty<float>(this.Props, "MaxDampStrengthY", 0.0f); this.MaxDampStrengthZ = new SimpleProperty<float>(this.Props, "MaxDampStrengthZ", 0.0f); this.PreferredAngleX = new SimpleProperty<float>(this.Props, "PreferredAngleX", 0.0f); this.PreferredAngleY = new SimpleProperty<float>(this.Props, "PreferredAngleY", 0.0f); this.PreferredAngleZ = new SimpleProperty<float>(this.Props, "PreferredAngleZ", 0.0f); this.Show = new SimpleProperty<bool>(this.Props, "Show", true); this.LODBox = new SimpleProperty<bool>(this.Props, "LODBox", false); this.Freeze = new SimpleProperty<bool>(this.Props, "Freeze", false); }
private void ReadPropertyTemplates() { Scope sc = parser.RootScope; Element edefs = sc["Definitions"]; if (edefs == null || edefs.Compound == null) { Console.Error.WriteLine("no Definitions dictionary found"); return; } Scope sdefs = edefs.Compound; List<Element> otypes = sdefs.GetCollection("ObjectType"); foreach(Element el in otypes) { Scope sc2 = el.Compound; if (sc2 == null) { Console.Error.WriteLine("expected nested scope in ObjectType, ignoring"); continue; } List<Token> tok = el.Tokens; if (tok.Count == 0) { Console.Error.WriteLine("expected name for ObjectType element, ignoring"); continue; } string oname = Parser.ParseTokenAsString(tok[0]); List<Element> templs = sc2.GetCollection("PropertyTemplate"); if (templs != null) { foreach (Element el3 in templs) { Scope sc3 = el3.Compound; if (sc3 == null) { Console.Error.WriteLine("expected nested scope in PropertyTemplate, ignoring"); continue; } List<Token> tok2 = el3.Tokens; if (tok2.Count == 0) { Console.Error.WriteLine("expected name for PropertyTemplate element, ignoring"); continue; } string pname = Parser.ParseTokenAsString(tok2[0]); Element properties70 = sc3["Properties70"]; if (properties70 != null) { PropertyTable props = new PropertyTable(properties70, new PropertyTable()); templates[oname + "." + pname] = props; } } } } }
public PropertyTable() { this.templateProps = null; this.element = null; }
/// <summary> /// the optional whitelist specifies a list of property names for which the caller /// wants animations for. If the curve node does not match one of these, std::range_error /// will be thrown. /// </summary> public AnimationCurveNode(ulong id, Element element, string name, Document doc, string[] targetPropWhitelist = null) : base(id, element, name) { this.doc = doc; this.target = null; curves = new Dictionary<string, AnimationCurve>(); var sc = Parser.GetRequiredScope(element); // find target node var whitelist = new[] { "Model", "NodeAttribute" }; var conns = doc.GetConnectionsBySourceSequenced(ID, whitelist); foreach(var con in conns) { // link should go for a property if (string.IsNullOrEmpty(con.PropertyName)) { continue; } if (targetPropWhitelist != null) { var s = con.PropertyName; var ok = false; for(int i=0; i<whitelist.Length; ++i) { if (s == targetPropWhitelist[i]) { ok = true; break; } } if (!ok) { throw (new ArgumentOutOfRangeException("AnimationCurveNode target property is not in whitelist")); } } var ob = con.DestinationObject; if (ob == null) { DocumentUtil.DOMWarning("failed to read destination object for AnimationCurveNode->Model link, ignoring", element); continue; } // XXX support constraints as DOM class //ai_assert(dynamic_cast<const Model*>(ob) || dynamic_cast<const NodeAttribute*>(ob)); target = ob; if (target == null) { continue; } prop = con.PropertyName; break; } if (target == null) { DocumentUtil.DOMWarning("failed to resolve target Model/NodeAttribute/Constraint for AnimationCurveNode", element); } props = DocumentUtil.GetPropertyTable(doc, "AnimationCurveNode.FbxAnimCurveNode", element, sc, false); }
public Material(ulong id, Element element, Document doc, string name) : base(id, element, name) { var sc = Parser.GetRequiredScope(element); var ShadingModel = sc["ShadingModel"]; var MultiLayer = sc["MultiLayer"]; if (MultiLayer != null) { this.multilayer = (Parser.ParseTokenAsID(Parser.GetRequiredToken(MultiLayer, 0)) != 0); } if (ShadingModel != null) { this.shading = Parser.ParseTokenAsString(Parser.GetRequiredToken(ShadingModel, 0)); } else { DocumentUtil.DOMWarning("shading mode not specified, assuming phong", element); shading = "phong"; } var templateName = string.Empty; var sh = shading; if (sh == "phong") { templateName = "Material.FbxSurfacePhong"; } else if (sh == "lambert") { templateName = "Material.FbxSurfaceLambert"; } else { DocumentUtil.DOMWarning("shading mode not recognized: " + shading, element); } props = DocumentUtil.GetPropertyTable(doc, templateName, element, sc); // resolve texture links var conns = doc.GetConnectionsByDestinationSequenced(ID); foreach (var con in conns) { // texture link to properties, not objects if (string.IsNullOrEmpty(con.PropertyName)) { continue; } var ob = con.SourceObject; if (ob == null) { DocumentUtil.DOMWarning("failed to read source object for texture link, ignoring", element); continue; } var tex = ob as Texture; if (tex == null) { var layeredTexture = ob as LayeredTexture; if (layeredTexture == null) { DocumentUtil.DOMWarning("source object for texture link is not a texture or layered texture, ignoring", element); continue; } var prop = con.PropertyName; if (layeredTextures.ContainsKey(prop)) { DocumentUtil.DOMWarning("duplicate layered texture link: " + prop, element); } layeredTextures[prop] = layeredTexture; layeredTexture.FillTexture(doc); } else { var prop = con.PropertyName; if (textures.ContainsKey(prop)) { DocumentUtil.DOMWarning("duplicate texture link: " + prop, element); } textures[prop] = tex; } } }
private void SetShadingPropertiesCommon(aiMaterial outMat, PropertyTable props) { bool ok; var diffuse = GetColorPropertyFromMaterial(props, "Diffuse", out ok); if (ok) { outMat.ColorDiffuse = new Color4(diffuse, 1.0f); } var emissive = GetColorPropertyFromMaterial(props, "Emissive", out ok); if (ok) { outMat.ColorEmissive = new Color4(emissive, 1.0f); } var ambient = GetColorPropertyFromMaterial(props, "Ambient", out ok); if (ok) { outMat.ColorAmbient = new Color4(ambient, 1.0f); } var specular = GetColorPropertyFromMaterial(props, "Specular", out ok); if (ok) { outMat.ColorSpecular = new Color4(specular, 1.0f); } float opacity = PropertyHelper.PropertyGet<float>(props, "Opacity", out ok); if (ok) { outMat.Opacity = opacity; } float reflectivity = PropertyHelper.PropertyGet<float>(props, "Reflectivity", out ok); if (ok) { outMat.Reflectivity = reflectivity; } float shininess = PropertyHelper.PropertyGet<float>(props, "Shininess", out ok); if (ok) { outMat.Shininess = shininess; } float shininessExponent = PropertyHelper.PropertyGet<float>(props, "ShininessExponent", out ok); if (ok) { outMat.ShininessStrength = shininessExponent; } }
private Color3 GetColorPropertyFromMaterial(PropertyTable props, string baseName, out bool result) { result = true; bool ok; var diffuse = PropertyHelper.PropertyGet<Vector3>(props, baseName, out ok); if (ok) { return new Color3(diffuse.X, diffuse.Y, diffuse.Z); } else { Vector3 diffuseColor = PropertyHelper.PropertyGet<Vector3>(props, baseName + "Color", out ok); if (ok) { float diffuseFactor = PropertyHelper.PropertyGet<float>(props, baseName + "Factor", out ok); if (ok) { diffuseColor *= diffuseFactor; } return new Color3(diffuseColor.X, diffuseColor.Y, diffuseColor.Z); } } result = false; return new Color3(0, 0, 0); }