/// <summary> /// Stores the current selected technique and if the texture uses alpha /// into the mesh name for each mesh part. /// </summary> private void StoreEffectTechniqueInMeshName( NodeContent input, ContentProcessorContext context) { MeshContent mesh = input as MeshContent; if (mesh != null) { foreach (GeometryContent geom in mesh.Geometry) { EffectMaterialContent effectMaterial = geom.Material as EffectMaterialContent; if (effectMaterial != null) { if (effectMaterial.OpaqueData.ContainsKey("technique")) { // Store technique here! (OpaqueData["technique"] is an int32) input.Name = input.Name + effectMaterial.OpaqueData["technique"]; } // if } // if } // foreach } // if // Go through all childs foreach (NodeContent child in input.Children) { StoreEffectTechniqueInMeshName(child, context); } // foreach }
public override ModelContent Process(NodeContent input, ContentProcessorContext context) { if (input == null) { throw new ArgumentNullException("input"); } //we always want to generate tangent frames, as we use tangent space normal mapping GenerateTangentFrames = true; //merge transforms MeshHelper.TransformScene(input, input.Transform); input.Transform = Matrix.Identity; if (!_isSkinned) MergeTransforms(input); ModelContent model = base.Process(input, context); //gather some information that will be useful in run time MeshMetadata metadata = new MeshMetadata(); BoundingBox aabb = new BoundingBox(); metadata.BoundingBox = ComputeBoundingBox(input, ref aabb, metadata); //assign it to our Tag model.Tag = metadata; return model; }
public override TImport Import(string filename, ContentImporterContext context) { _context = context; // _animfiles will contain list of new temp anim files. _animfiles = new List <string>(); // Decouple header and animation data. ExtractAnimations(filename); // Process master file (this will also process the first animation) _master = base.Import(filename, context); // Process the remaining animations. foreach (string file in _animfiles) { TImport anim = base.Import(file, context); // Append animation to master NodeContent. AppendAnimation(_master, anim); } // Delete the temporary animation files. DeleteTempFiles(); return(_master); }
/// <summary> /// The main Process method converts an intermediate format content pipeline /// NodeContent tree to a ModelContent object with embedded animation data. /// </summary> public override ModelContent Process(NodeContent input, ContentProcessorContext context) { SkinningData skinningData = SkinningHelpers.GetSkinningData(input, context, SkinnedEffect.MaxBones); ModelContent model = base.Process(input, context); model.Tag = skinningData; return model; }
protected virtual void FlattenTransforms(NodeContent node, NodeContent stopper, ContentProcessorContext context) { if (node == stopper) { BakeTransformsToTop(node.Parent); return; } MeshContent mc = node as MeshContent; if (mc != null) { foreach (GeometryContent gc in mc.Geometry) { if (VerticesAreSkinned(gc.Vertices, context)) { BakeTransformsToTop(node); break; } } } foreach (NodeContent child in node.Children) { FlattenTransforms(child, stopper, context); } }
public override ModelContent Process(NodeContent input, ContentProcessorContext context) { ModelContent model = base.Process(input, context); //results will be stored in this collection List<Vector3> points = new List<Vector3>(); //loop throught each mesh at the center of each of its bounding spheres foreach (ModelMeshContent mesh in model.Meshes) { //we will need to transform the center by the meshes parent bone atrix //if we don't they will all be at the same position Matrix transform; if (mesh.ParentBone.Transform != null) transform = mesh.ParentBone.Transform; var p = Vector3.Transform(mesh.BoundingSphere.Center, mesh.ParentBone.Transform); //using the property above we can make decisions if (PreservePointHeight) points.Add(p); else points.Add(new Vector3(p.X,0,p.Z)); } //we always store the additional data in the Tag property of the object model.Tag = points; return model; }
public override TImport Import(string filename, ContentImporterContext context) { _context = context; // _animfiles will contain list of new temp anim files. _animfiles = new List<string>(); // Decouple header and animation data. ExtractAnimations(filename); // Process master file (this will also process the first animation) _master = base.Import(filename, context); // Process the remaining animations. foreach (string file in _animfiles) { TImport anim = base.Import(file, context); // Append animation to master NodeContent. AppendAnimation(_master, anim); } // Delete the temporary animation files. DeleteTempFiles(); return _master; }
private List<Triangle> AddVerticesToList(NodeContent node, List<Triangle> triangleList) { MeshContent mesh = node as MeshContent; if (mesh != null) { Matrix abstransform = mesh.AbsoluteTransform; foreach (GeometryContent geo in mesh.Geometry) { int triangles = geo.Indices.Count / 3; for (int currentTriangle = 0; currentTriangle < triangles; ++currentTriangle) { int index0 = geo.Indices[currentTriangle * 3 + 0]; int index1 = geo.Indices[currentTriangle * 3 + 1]; int index2 = geo.Indices[currentTriangle * 3 + 2]; Vector3 v0 = geo.Vertices.Positions[index0]; Vector3 v1 = geo.Vertices.Positions[index1]; Vector3 v2 = geo.Vertices.Positions[index2]; Vector3 transv0 = Vector3.Transform(v0, abstransform); Vector3 transv1 = Vector3.Transform(v1, abstransform); Vector3 transv2 = Vector3.Transform(v2, abstransform); Triangle newTriangle = new Triangle(transv0, transv1, transv2); triangleList.Add(newTriangle); } } } foreach (NodeContent child in node.Children) triangleList = AddVerticesToList(child, triangleList); return triangleList; }
public override ModelContent Process(NodeContent input, ContentProcessorContext context) { model = base.Process(input, context); AnimationClips clips = ProcessAnimations(model, input, context); model.Tag = clips; return model; }
protected virtual SkinnedBone[] GetInverseBindPose(NodeContent input, ContentProcessorContext context, BoneContent skeleton) { if (skeleton == null) { return(null); } IList <BoneContent> original = MeshHelper.FlattenSkeleton(skeleton); if (original.Count > maxNumBones_) { throw new System.ArgumentException(String.Format( "The animation processor found {0} bones in the skeleton; a maximum of {1} is allowed.", original.Count, maxNumBones_)); } List <SkinnedBone> inversePose = new List <SkinnedBone>(); foreach (BoneContent bc in original) { SkinnedBone sb = new SkinnedBone(); sb.Name = bc.Name; if (sb.Name == null) { throw new System.ArgumentNullException("Bone with null name found."); } sb.InverseBindTransform = Matrix.Invert(GetAbsoluteTransform(bc, null)); inversePose.Add(sb); } return(inversePose.ToArray()); }
public override ModelContent Process(NodeContent input, ContentProcessorContext context) { ValidateMesh(input, context, null); BoneContent skeleton = MeshHelper.FindSkeleton(input); if (skeleton == null) throw new InvalidContentException("Input skeleton not found."); //Bakes everything FlattenTransforms(input, skeleton); //Read bind pse and skeleton hierarchy data. IList<BoneContent> bones = MeshHelper.FlattenSkeleton(skeleton); if (bones.Count > SkinnedEffect.MaxBones) { throw new InvalidContentException(string.Format("Skeleton has {0} bones, but the max is {1}.", bones.Count, SkinnedEffect.MaxBones)); } List<Matrix> bindPose = new List<Matrix>(); List<Matrix> inverseBindPose = new List<Matrix>(); List<int> skeletonHierarchy = new List<int>(); Dictionary<string, int> boneIndices = new Dictionary<string, int>(); foreach (BoneContent bone in bones) { bindPose.Add(bone.Transform); inverseBindPose.Add(Matrix.Invert(bone.AbsoluteTransform)); skeletonHierarchy.Add(bones.IndexOf(bone.Parent as BoneContent)); boneIndices.Add(bone.Name, boneIndices.Count); } ModelContent model = base.Process(input, context); model.Tag = new SkinningDataStorage(bindPose, inverseBindPose, skeletonHierarchy, boneIndices); return model; }
/// <summary> /// Helper for extracting a list of all the vertex positions in a model. /// </summary> void FindVertices(NodeContent node) { // Is this node a mesh? MeshContent mesh = node as MeshContent; if (mesh != null) { // Look up the absolute transform of the mesh. //Matrix absoluteTransform = mesh.AbsoluteTransform; // Loop over all the pieces of geometry in the mesh. foreach (GeometryContent geometry in mesh.Geometry) { // Loop over all the indices in this piece of geometry. // Every group of three indices represents one triangle. foreach (int index in geometry.Indices) { // Look up the position of this vertex. Vector3 vertex = geometry.Vertices.Positions[index]; // Transform from local into world space. //vertex = Vector3.Transform(vertex, absoluteTransform); // Store this vertex. vertices.Add(vertex); } } } // Recursively scan over the children of this node. foreach (NodeContent child in node.Children) { FindVertices(child); } }
public override ModelContent Process(NodeContent input, ContentProcessorContext context) { // Break up the mesh to separate triangles. NodeContent processedNode = ProcessMesh(input); return base.Process(processedNode, context); }
public override ModelContent Process(NodeContent input, ContentProcessorContext context) { CompileRegularExpressions(); context.Logger.LogMessage("Output Platform: {0}", context.TargetPlatform); maxScale_ = 0; maxOffset_ = 0; BoneContent skeleton = MeshHelper.FindSkeleton(input); FlattenTransforms(input, skeleton, context); SkinnedBone[] inverseBindPose = GetInverseBindPose(input, context, skeleton); context.Logger.LogMessage("Found {0} skinned bones in skeleton.", (inverseBindPose == null) ? 0 : inverseBindPose.Length); ModelContent output = base.Process(input, context); if (output.Tag == null) { output.Tag = new Dictionary <string, object>(); } if (FoundSkinning) { #if DEBUG StringBuilder strb = new StringBuilder(); #endif if (inverseBindPose == null) { throw new System.Exception("Could not find skeleton although there is skinned data."); } for (int i = 0; i != inverseBindPose.Length; ++i) { SkinnedBone sb = inverseBindPose[i]; int q = 0; sb.Index = -1; foreach (ModelBoneContent mbc in output.Bones) { if (mbc.Name == sb.Name) { sb.Index = mbc.Index; break; } ++q; } if (sb.Index == -1) { throw new System.ArgumentException( String.Format("Can't find the index for animated bone named {0}.", sb.Name)); } inverseBindPose[i] = sb; } ((Dictionary <string, object>)output.Tag).Add("InverseBindPose", inverseBindPose); } ((Dictionary <string, object>)output.Tag).Add("AnimationSet", BuildAnimationSet(input, ref output, context)); ((Dictionary <string, object>)output.Tag).Add("BoundsInfo", new BoundsInfo(maxScale_, maxOffset_)); return(output); }
public void CalculateBoundingBox(NodeContent node) { MeshContent mesh = node as MeshContent; if (mesh != null) { // calculating max and min points coordinates foreach (Vector3 vertex in mesh.Positions) { if (vertex.X < minPoint.X) minPoint.X = vertex.X; if (vertex.Y < minPoint.Y) minPoint.Y = vertex.Y; if (vertex.Z < minPoint.Z) minPoint.Z = vertex.Z; if (vertex.X > maxPoint.X) maxPoint.X = vertex.X; if (vertex.Y > maxPoint.Y) maxPoint.Y = vertex.Y; if (vertex.Z > maxPoint.Z) maxPoint.Z = vertex.Z; } } else { // calling the function recursively for all the children nodes foreach (NodeContent childNode in node.Children) { this.CalculateBoundingBox(childNode); } } }
/// <summary> /// The main Process method converts an intermediate format content pipeline /// NodeContent tree to a ModelConte nt object with embedded animation data. /// </summary> public override ModelContent Process(NodeContent input, ContentProcessorContext context) { ValidateMesh(input, context, null); List<int> boneHierarchy = new List<int>(); // Chain to the base ModelProcessor class so it can convert the model data. ModelContent model = base.Process(input, context); // Add each of the bones foreach (ModelBoneContent bone in model.Bones) { boneHierarchy.Add(model.Bones.IndexOf(bone.Parent as ModelBoneContent)); } // Animation clips inside the object (mesh) Dictionary<string, ModelAnimationClip> animationClips = new Dictionary<string, ModelAnimationClip>(); // Animation clips at the root of the object Dictionary<string, ModelAnimationClip> rootClips = new Dictionary<string, ModelAnimationClip>(); // Process the animations ProcessAnimations(input, model, animationClips, rootClips); // Store the data for the model model.Tag = new ModelData(animationClips, rootClips, null, null, boneHierarchy); return model; }
/// <summary> /// The main method in charge of processing the content. /// </summary> public override ModelContent Process(NodeContent input, ContentProcessorContext context) { // Chain to the base ModelProcessor class. ModelContent model = base.Process(input, context); // Look up the input vertex positions. FindVertices(input); // You can store any type of object in the model Tag property. This // sample only uses built-in types such as string, Vector3, BoundingSphere, // dictionaries, and arrays, which the content pipeline knows how to // serialize by default. We could also attach custom data types here, but // then we would have to provide a ContentTypeWriter and ContentTypeReader // implementation to tell the pipeline how to serialize our custom type. // // We are setting our model Tag to a dictionary that maps strings to // objects, and then storing two different kinds of custom data into that // dictionary. This is a useful pattern because it allows processors to // combine many different kinds of information inside the single Tag value. Dictionary<string, object> tagData = new Dictionary<string, object>(); model.Tag = tagData; // Store vertex information in the tag data, as an array of Vector3. tagData.Add("Vertices", vertices.ToArray()); // Also store a custom bounding sphere. tagData.Add("BoundingSphere", BoundingSphere.CreateFromPoints(vertices)); return model; }
protected virtual AnimationContentDictionary MergeAnimatedBones(NodeContent root) { AnimationContentDictionary ret = new AnimationContentDictionary(); CollectAnimatedBones(ret, root); return(ret); }
/// <summary> /// The main Process method converts an intermediate format content pipeline /// NodeContent tree to a ModelContent object with embedded animation data. /// </summary> public override ModelContent Process(NodeContent input, ContentProcessorContext context) { contentPath = Environment.CurrentDirectory; using (XmlReader reader = XmlReader.Create(MaterialDataFilePath)) { incomingMaterials = IntermediateSerializer.Deserialize<List<MaterialData>>(reader, null); } context.AddDependency(Path.Combine(Environment.CurrentDirectory, MaterialDataFilePath)); // Chain to the base ModelProcessor class so it can convert the model data. ModelContent model = base.Process(input, context); // Put the material's flags into the ModelMeshPartContent's Tag property. foreach (ModelMeshContent mmc in model.Meshes) { foreach (ModelMeshPartContent mmpc in mmc.MeshParts) { MaterialData mat = incomingMaterials.Single(m => m.Name == mmpc.Material.Name); MaterialInfo extraInfo = new MaterialInfo(); extraInfo.HandlingFlags = mat.HandlingFlags; extraInfo.RenderState = mat.RenderState; mmpc.Tag = extraInfo; } } return model; }
/// <summary> /// The main Process method converts an intermediate format content pipeline /// NodeContent tree to a ModelContent object with embedded animation data. /// </summary> public override ModelContent Process(NodeContent input, ContentProcessorContext context) { ValidateMesh(input, context, null); // Find the skeleton. BoneContent skeleton = MeshHelper.FindSkeleton(input); if (skeleton == null) throw new InvalidContentException("Input skeleton not found."); // We don't want to have to worry about different parts of the model being // in different local coordinate systems, so let's just bake everything. FlattenTransforms(input, skeleton); // Read the bind pose and skeleton hierarchy data. IList<BoneContent> bones = MeshHelper.FlattenSkeleton(skeleton); if (bones.Count > SkinnedEffect.MaxBones) { throw new InvalidContentException(string.Format( "Skeleton has {0} bones, but the maximum supported is {1}.", bones.Count, SkinnedEffect.MaxBones)); } List<Matrix> bindPose = new List<Matrix>(); List<Matrix> inverseBindPose = new List<Matrix>(); List<int> skeletonHierarchy = new List<int>(); #region BaamStudios XnaMixamoImporter Change List<string> boneNames = new List<string>(); #endregion foreach (BoneContent bone in bones) { bindPose.Add(bone.Transform); inverseBindPose.Add(Matrix.Invert(bone.AbsoluteTransform)); skeletonHierarchy.Add(bones.IndexOf(bone.Parent as BoneContent)); #region BaamStudios XnaMixamoImporter Change boneNames.Add(bone.Name); #endregion } // Convert animation data to our runtime format. Dictionary<string, AnimationClip> animationClips; animationClips = ProcessAnimations(skeleton.Animations, bones); // Chain to the base ModelProcessor class so it can convert the model data. ModelContent model = base.Process(input, context); // Store our custom animation data in the Tag property of the model. model.Tag = new SkinningData(animationClips, bindPose, inverseBindPose, skeletonHierarchy #region BaamStudios XnaMixamoImporter Change , boneNames #endregion ); return model; }
/// <summary> /// Calculate a bounding box for the model. /// </summary> /// <param name="model">The model to calculate AABBs for</param> public static void CalculateBoundingBox(NodeContent input, ModelContent model) { BoundingBox box = new BoundingBox(); CalculateBoundingBox(input, ref box); if (model.Tag == null) model.Tag = new Dictionary<string, object>(); (model.Tag as Dictionary<string, object>).Add("BoundingBox", box); }
public override ModelContent Process( NodeContent input, ContentProcessorContext context ) { ModelContent model = base.Process( input, context ); model.Tag = 21; // soft body object here return model; }
private void CalculateTangentFrames( NodeContent input, ContentProcessorContext context ) { MeshContent inputMesh = input as MeshContent; if( inputMesh != null ) MeshHelper.CalculateTangentFrames( inputMesh, VertexChannelNames.TextureCoordinate( 0 ), VertexChannelNames.Tangent( 0 ), null ); foreach( NodeContent childNode in input.Children ) CalculateTangentFrames( childNode, context ); }
public override ModelContent Process(NodeContent input, ContentProcessorContext context) { ValidateMesh(input, context, null); //Generate Tangents/Normals for shader MeshContent mesh = input as MeshContent; if (mesh != null) { MeshHelper.CalculateTangentFrames(mesh, VertexChannelNames.TextureCoordinate(0), VertexChannelNames.Tangent(0), VertexChannelNames.Binormal(0)); } // Find the skeleton. BoneContent skeleton = MeshHelper.FindSkeleton(input); if (skeleton == null) throw new InvalidContentException("Input skeleton not found."); // We don't want to have to worry about different parts of the model being // in different local coordinate systems, so let's just bake everything. FlattenTransforms(input, skeleton); // Read the bind pose and skeleton hierarchy data. IList<BoneContent> bones = MeshHelper.FlattenSkeleton(skeleton); if (bones.Count > SkinnedEffect.MaxBones) { throw new InvalidContentException(string.Format( "Skeleton has {0} bones, but the maximum supported is {1}.", bones.Count, SkinnedEffect.MaxBones)); } List<Matrix> bindPose = new List<Matrix>(); List<Matrix> inverseBindPose = new List<Matrix>(); List<int> skeletonHierarchy = new List<int>(); foreach (BoneContent bone in bones) { bindPose.Add(bone.Transform); inverseBindPose.Add(Matrix.Invert(bone.AbsoluteTransform)); skeletonHierarchy.Add(bones.IndexOf(bone.Parent as BoneContent)); } // Chain to the base BShiftModelProcessor class so it can convert the model data. ModelContent model = base.Process(input, context); // Convert animation data to our runtime format. Dictionary<string, AnimationClip> animationClips; animationClips = ProcessAnimations(skeleton.Animations, bones); ((Dictionary<string, object>)model.Tag).Add("SkinningData", new SkinningData(animationClips, bindPose, inverseBindPose, skeletonHierarchy)); return model; }
public override ModelContent Process(NodeContent input, ContentProcessorContext context) { if (input == null) { throw new ArgumentNullException("input"); } return base.Process(input, context); }
/// <summary> /// Converts mesh content to model content with a <see cref="TriangleMeshShape"/>. /// </summary> /// <param name="input">The root node content.</param> /// <param name="context">Context for the specified processor.</param> /// <returns>The <see cref="Shape"/>.</returns> public override DRModelNodeContent Process(NodeContent input, ContentProcessorContext context) { // ----- Process Model var model = base.Process(input, context); // ----- Extract Triangles var triangleMesh = new TriangleMesh(); // The input node is usually a tree of nodes. We need to collect all MeshContent nodes // in the tree. The DigitalRune Helper library provides a TreeHelper that can be used // to traverse trees using LINQ. // The following returns an IEnumerable that returns all nodes of the tree. var nodes = TreeHelper.GetSubtree(input, n => n.Children); // We only need nodes of type MeshContent. var meshes = nodes.OfType<MeshContent>(); foreach (var mesh in meshes) { // Apply any transformations to vertices. Matrix transform = mesh.AbsoluteTransform; for (int i = 0; i < mesh.Positions.Count; i++) mesh.Positions[i] = Vector3.Transform(mesh.Positions[i], transform); // Extract triangles from submeshes. foreach (var geometry in mesh.Geometry) { int numberOfTriangles = geometry.Indices.Count / 3; for (int i = 0; i < numberOfTriangles; i++) { int index0 = geometry.Indices[3 * i + 0]; int index1 = geometry.Indices[3 * i + 2]; // Note: DigitalRune Geometry uses a different winding int index2 = geometry.Indices[3 * i + 1]; // order. Therefore, the indices need to be swapped. Vector3F vertex0 = (Vector3F)geometry.Vertices.Positions[index0]; Vector3F vertex1 = (Vector3F)geometry.Vertices.Positions[index1]; Vector3F vertex2 = (Vector3F)geometry.Vertices.Positions[index2]; triangleMesh.Add(new Triangle(vertex0, vertex1, vertex2), false, Numeric.EpsilonF, true); } } } // Remove duplicate vertices. triangleMesh.WeldVertices(); // ----- Create TriangleMeshShape // Create a TriangleMeshShape that can be used for collision detection. // Note: // - Contact-welding is enabled to improve the results of the collision detection. // - A CompressedAabbTree is used for spatial partitioning to speed up collision detection. var triangleMeshShape = new TriangleMeshShape(triangleMesh, true, new CompressedAabbTree()); // Export the ModelNode together with the TriangleMeshShape. model.UserData = triangleMeshShape; return model; }
public override TOutput Process(TInput input, ContentProcessorContext context) { this.context = context; CollisionContent cc = ProcessCollision(input); ModelContent mc = base.Process(input, context); ((Dictionary <string, object>)mc.Tag).Add("Collision", cc); return(mc); }
/// <summary> /// The main Process method converts an intermediate format content pipeline /// NodeContent tree to a ModelContent object with embedded animation data. /// </summary> public override ModelContent Process(NodeContent input, ContentProcessorContext context) { m_IsSkinned = true; // Rotation correction from blender RotationX = -90; return base.Process(input, context); }
public override ModelContent Process(NodeContent input, ContentProcessorContext context) { //allocates list that stores values from the processor to the ScreenModel class ToSendInTag = new List<object>(); CollisionBox = new BoundingBox(); //code that builds/creates the bounding box for collisions //gets the node data from the model-> allows us to go in further through meshes later to find vector sizes NodeContentCollection nodeContentCollection = input.Children; ModelContent TheContent = base.Process(input, context); //CollisionType = new ObjectTypes((int)CollisionArg); Enum EnumWrapper = CollisionArg; //tags the collision box...allows us to reference them outside...I've used tags before; they are cool and weird //As I need to send multiple values through the tag; why not use a list of generic objects? //ToSendInTag.Add(EnumWrapper); ToSendInTag.Add((int)CollisionArg); //only processes the shape of the bounding box when the bounding box is required, saves memory and processing time if (CollisionArg == CollisionKind.Box) { //for objects that are better off using a bounding box FindVectorValues(nodeContentCollection); ToSendInTag.Add(CollisionBox); } if (CollisionArg == CollisionKind.Room) { //calculates bounding collision box FindVectorValues(nodeContentCollection); //gets the points of the corners; should be 8 of them Vector3[] ListOfCorners = CollisionBox.GetCorners(); //uses maths to get planes from these corners // 1 2 5 6 // 3 4 7 8 // up down //needs to get a total of 6 walls //create a list of planes to send over that represent the walls of a room List<Plane> ListOfWalls = new List<Plane>(); //6 sides are recieved from using 3 points on each of the planes //#1- pts: 1,2,3 ListOfWalls.Add(new Plane(ListOfCorners[0],ListOfCorners[1],ListOfCorners[2])); //#2- pts: 1,5,6 ListOfWalls.Add(new Plane(ListOfCorners[0], ListOfCorners[4], ListOfCorners[5])); //#3- pts: 2,6,8 ListOfWalls.Add(new Plane(ListOfCorners[1], ListOfCorners[5], ListOfCorners[7])); //#4- pts: 4,7,8 ListOfWalls.Add(new Plane(ListOfCorners[3], ListOfCorners[6], ListOfCorners[7])); //#5- pts: 3,5,7 ListOfWalls.Add(new Plane(ListOfCorners[2], ListOfCorners[4], ListOfCorners[6])); //#6- pts: 5,6,8 ListOfWalls.Add(new Plane(ListOfCorners[4], ListOfCorners[5], ListOfCorners[7])); //added to the tag array ToSendInTag.Add(ListOfWalls); } //sends over the list TheContent.Tag = ToSendInTag; //returns the modified data with the tag (reference) to the bounding box return (TheContent); }
public override ModelContent Process(NodeContent input, ContentProcessorContext context) { ModelContent model = base.Process(input, context); FindVertices(input); model.Tag = vertices; return model; }
public override ModelContent Process(NodeContent input, ContentProcessorContext context) { ModelContent usualModel = base.Process(input, context); List<Triangle> triangles = new List<Triangle>(); triangles = AddVerticesToList(input, triangles); usualModel.Tag = triangles.ToArray(); return usualModel; }
public override ModelContent Process(NodeContent input, ContentProcessorContext context) { var model = base.Process(input, context); var animFile = Path.ChangeExtension(context.OutputFilename, ".anim"); SaveSkinningData((SkinningData)model.Tag, animFile); return model; }
public override ModelContent Process(NodeContent input, ContentProcessorContext context) { if (input == null) { throw new ArgumentNullException("input"); } context.Logger.LogImportantMessage("processing: " + input.Name); PreprocessSceneHierarchy(input, context, input.Name); return base.Process(input, context); }
public override ModelContent Process(NodeContent input, ContentProcessorContext context) { if (input == null) { throw new ArgumentNullException("input"); } modelDirectory = Path.GetDirectoryName(input.Identity.SourceFilename); AddSpecularMap(input); return base.Process(input, context); }
public override ModelContent Process( NodeContent input, ContentProcessorContext context ) { CalculateTangentFrames( input, context ); ModelContent modelContent = base.Process( input, context ); foreach( ModelMeshContent modelMesh in modelContent.Meshes ) { foreach( ModelMeshPartContent modelMeshPart in modelMesh.MeshParts ) modelMeshPart.Tag = modelMeshPart.Material.Name; } return modelContent; }
public static void RotateAll(NodeContent node, float degX, float degY, float degZ) { Matrix rotate = Matrix.Identity * Matrix.CreateRotationX(MathHelper.ToRadians(degX)) * Matrix.CreateRotationY(MathHelper.ToRadians(degY)) * Matrix.CreateRotationZ(MathHelper.ToRadians(degZ)); MeshHelper.TransformScene(node, rotate); }
protected static Matrix GetAbsoluteTransform(NodeContent mbc, NodeContent relativeTo) { Matrix mat = Matrix.Identity; // avoid recursion while (mbc != null && mbc != relativeTo) { mat = mat * mbc.Transform; mbc = mbc.Parent; } return(mat); }
// If there are articulating bones above the skinned mesh or skeleton in the mesh, // those will be flattened. Put them further down in the hierarchy if you care. protected virtual void BakeTransformsToTop(NodeContent node) { while (node != null) { if (!node.Transform.Equals(Matrix.Identity)) { MeshHelper.TransformScene(node, node.Transform); node.Transform = Matrix.Identity; // because I baked this node, I can't animate it! node.Animations.Clear(); } node = node.Parent; } }
protected virtual void CollectAnimatedBones(AnimationContentDictionary dict, NodeContent bone) { AnimationContentDictionary acd = bone.Animations; if (acd != null) { foreach (string name in acd.Keys) { // merge each animation into the dictionary AnimationContent ac = acd[name]; AnimationContent xac; if (!dict.TryGetValue(name, out xac)) { // create it if we haven't already seen it, and there's something there if (ac.Channels.Count > 0) { xac = ac; dict.Add(name, xac); } } else { // merge the animation content foreach (KeyValuePair <string, AnimationChannel> kvp in ac.Channels) { AnimationChannel ov; if (xac.Channels.TryGetValue(kvp.Key, out ov)) { throw new System.ArgumentException( String.Format("The animation {0} has multiple channels named {1}.", name, kvp.Key)); } xac.Channels.Add(kvp.Key, kvp.Value); } xac.Duration = new TimeSpan((long) (Math.Max(xac.Duration.TotalSeconds, ac.Duration.TotalSeconds) * 1e7)); } } } foreach (NodeContent nc in bone.Children) { CollectAnimatedBones(dict, nc); } }
public static BoneContent FindSkeleton(NodeContent node) { throw new NotImplementedException(); }
/// <summary> /// The workhorse of the animation processor. It loops through all /// animations, all tracks, and all keyframes, and converts to the format /// expected by the runtime animation classes. /// </summary> /// <param name="input">The NodeContent to process. Comes from the base ModelProcessor.</param> /// <param name="output">The ModelContent that was produced. You don't typically change this.</param> /// <param name="context">The build context (logger, etc).</param> /// <returns>An allocated AnimationSet with the animations to include.</returns> public virtual AnimationSet BuildAnimationSet(NodeContent input, ref ModelContent output, ContentProcessorContext context) { AnimationSet ret = new AnimationSet(); if (!DoAnimations) { context.Logger.LogImportantMessage("DoAnimation is set to false for {0}; not generating animations.", input.Name); return(ret); } // go from name to index Dictionary <string, ModelBoneContent> nameToIndex = new Dictionary <string, ModelBoneContent>(); foreach (ModelBoneContent mbc in output.Bones) { nameToIndex.Add(GetBoneName(mbc), mbc); } AnimationContentDictionary adict = MergeAnimatedBones(input); if (adict == null || adict.Count == 0) { context.Logger.LogWarning("http://kwxport.sourceforge.net/", input.Identity, "Model processed with AnimationProcessor has no animations."); return(ret); } foreach (AnimationContent ac in adict.Values) { if (!IncludeAnimation(ac)) { context.Logger.LogImportantMessage(String.Format("Not including animation named {0}.", ac.Name)); continue; } context.Logger.LogImportantMessage( "Processing animation {0} duration {1} sample rate {2} reduction tolerance {3}.", ac.Name, ac.Duration, SampleRate, Tolerance); AnimationChannelDictionary acdict = ac.Channels; AnimationTrackDictionary tracks = new AnimationTrackDictionary(); foreach (string name in acdict.Keys) { if (!IncludeTrack(ac, name)) { context.Logger.LogImportantMessage(String.Format("Not including track named {0}.", name)); continue; } int ix = 0; AnimationChannel achan = acdict[name]; int bix = nameToIndex[name].Index; context.Logger.LogMessage("Processing bone {0}:{1}.", name, bix); AnimationTrack at; if (tracks.TryGetValue(bix, out at)) { throw new System.ArgumentException( String.Format("Bone index {0} is used by multiple animations in the same clip (name {1}).", bix, name)); } // Sample at given frame rate from 0 .. Duration List <Keyframe> kfl = new List <Keyframe>(); int nFrames = (int)Math.Floor(ac.Duration.TotalSeconds * SampleRate + 0.5); for (int i = 0; i < nFrames; ++i) { Keyframe k = SampleChannel(achan, i / SampleRate, ref ix); kfl.Add(k); } // Run keyframe elimitation Keyframe[] frames = kfl.ToArray(); int nReduced = 0; if (tolerance_ > 0) { nReduced = ReduceKeyframes(frames, tolerance_); } if (nReduced > 0) { context.Logger.LogMessage("Reduced '{2}' from {0} to {1} frames.", frames.Length, frames.Length - nReduced, name); } // Create an AnimationTrack at = new AnimationTrack(bix, frames); tracks.Add(bix, at); } Animation a = new Animation(ac.Name, tracks, SampleRate); ret.AddAnimation(a); } // build the special "identity" and "bind pose" animations AnimationTrackDictionary atd_id = new AnimationTrackDictionary(); AnimationTrackDictionary atd_bind = new AnimationTrackDictionary(); foreach (KeyValuePair <string, ModelBoneContent> nip in nameToIndex) { Keyframe[] frames_id = new Keyframe[2]; frames_id[0] = new Keyframe(); frames_id[1] = new Keyframe(); AnimationTrack at_id = new AnimationTrack(nip.Value.Index, frames_id); atd_id.Add(nip.Value.Index, at_id); Keyframe[] frames_bind = new Keyframe[2]; Matrix mat = nip.Value.Transform; frames_bind[0] = Keyframe.CreateFromMatrix(mat); frames_bind[1] = new Keyframe(); frames_bind[1].CopyFrom(frames_bind[0]); AnimationTrack at_bind = new AnimationTrack(nip.Value.Index, frames_bind); atd_bind.Add(nip.Value.Index, at_bind); } ret.AddAnimation(new Animation("$id$", atd_id, 1.0f)); ret.AddAnimation(new Animation("$bind$", atd_bind, 1.0f)); return(ret); }
public static void TransformScene(NodeContent scene, Matrix transform) { throw new NotImplementedException(); }