/// <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
        }
Пример #2
0
        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;
 }
Пример #5
0
        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);
            }
        }
Пример #6
0
        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;
        }
Пример #7
0
        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;
        }
Пример #8
0
        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;
 }
Пример #10
0
        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);
 }
Пример #14
0
        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;
        }
Пример #18
0
        protected virtual AnimationContentDictionary MergeAnimatedBones(NodeContent root)
        {
            AnimationContentDictionary ret = new AnimationContentDictionary();

            CollectAnimatedBones(ret, root);
            return(ret);
        }
Пример #19
0
        /// <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);
 }
Пример #22
0
        public override ModelContent Process( NodeContent input, ContentProcessorContext context )
        {
            ModelContent model = base.Process( input, context );

              model.Tag = 21; // soft body object here

              return model;
        }
Пример #23
0
		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 );
		}
Пример #24
0
        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);
        }
Пример #26
0
    /// <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;
    }
Пример #27
0
        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;
        }
Пример #31
0
        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);
 }
Пример #34
0
        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);
        }
Пример #35
0
		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;
		}
Пример #36
0
        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);
        }
Пример #37
0
        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);
        }
Пример #38
0
 //  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;
     }
 }
Пример #39
0
        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);
            }
        }
Пример #40
0
 public static BoneContent FindSkeleton(NodeContent node)
 {
     throw new NotImplementedException();
 }
Пример #41
0
        /// <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);
        }
Пример #42
0
 public static void TransformScene(NodeContent scene, Matrix transform)
 {
     throw new NotImplementedException();
 }