diff --git a/ANX.Framework.sln b/ANX.Framework.sln index 798ddd8b..d9f3e566 100644 --- a/ANX.Framework.sln +++ b/ANX.Framework.sln @@ -138,6 +138,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "MediaSystems", "MediaSystem EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ANX.MediaSystem.Windows.OpenAL", "MediaSystems\ANX.MediaSystem.Windows.OpenAL\ANX.MediaSystem.Windows.OpenAL.csproj", "{97185A92-077D-4498-8B6A-8BFF04079044}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ModelSample", "Samples\ModelSample\ModelSample\ModelSample.csproj", "{ED081799-AB02-4793-96F8-F9EA7F3192E3}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -466,6 +468,16 @@ Global {97185A92-077D-4498-8B6A-8BFF04079044}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU {97185A92-077D-4498-8B6A-8BFF04079044}.Release|Mixed Platforms.Build.0 = Release|Any CPU {97185A92-077D-4498-8B6A-8BFF04079044}.Release|x86.ActiveCfg = Release|Any CPU + {ED081799-AB02-4793-96F8-F9EA7F3192E3}.Debug|Any CPU.ActiveCfg = Debug|x86 + {ED081799-AB02-4793-96F8-F9EA7F3192E3}.Debug|Mixed Platforms.ActiveCfg = Debug|x86 + {ED081799-AB02-4793-96F8-F9EA7F3192E3}.Debug|Mixed Platforms.Build.0 = Debug|x86 + {ED081799-AB02-4793-96F8-F9EA7F3192E3}.Debug|x86.ActiveCfg = Debug|x86 + {ED081799-AB02-4793-96F8-F9EA7F3192E3}.Debug|x86.Build.0 = Debug|x86 + {ED081799-AB02-4793-96F8-F9EA7F3192E3}.Release|Any CPU.ActiveCfg = Release|x86 + {ED081799-AB02-4793-96F8-F9EA7F3192E3}.Release|Mixed Platforms.ActiveCfg = Release|x86 + {ED081799-AB02-4793-96F8-F9EA7F3192E3}.Release|Mixed Platforms.Build.0 = Release|x86 + {ED081799-AB02-4793-96F8-F9EA7F3192E3}.Release|x86.ActiveCfg = Release|x86 + {ED081799-AB02-4793-96F8-F9EA7F3192E3}.Release|x86.Build.0 = Release|x86 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -491,6 +503,7 @@ Global {57097B7A-A283-4409-8AAC-35BF0F458657} = {9B0DD48B-3912-4F33-AF3F-691AF02B73F9} {160150D5-38E6-482D-97F5-2624F322A854} = {9B0DD48B-3912-4F33-AF3F-691AF02B73F9} {9C9C6245-35C2-4230-8E17-9038A228227F} = {9B0DD48B-3912-4F33-AF3F-691AF02B73F9} + {ED081799-AB02-4793-96F8-F9EA7F3192E3} = {9B0DD48B-3912-4F33-AF3F-691AF02B73F9} {DB88DDEB-7281-405D-8FCA-5681B6B2BD7A} = {7AD65E6B-2A48-437F-81D9-4CA9C9A85C64} {49066074-3B7B-4A55-B122-6BD33AB73558} = {7AD65E6B-2A48-437F-81D9-4CA9C9A85C64} {60D08399-244F-46A3-91F1-4CFD26D961A3} = {7AD65E6B-2A48-437F-81D9-4CA9C9A85C64} diff --git a/ANX.Framework/Content/ContentReader.cs b/ANX.Framework/Content/ContentReader.cs index 0cb51727..1e54b05b 100644 --- a/ANX.Framework/Content/ContentReader.cs +++ b/ANX.Framework/Content/ContentReader.cs @@ -249,12 +249,12 @@ namespace ANX.Framework.Content { return default(T); } - - if (index > this.typeReaders.Length) + index -= 1; + if (index >= this.typeReaders.Length) { throw new ContentLoadException("Bad Xnb"); } - ContentTypeReader reader = this.typeReaders[index-1]; + ContentTypeReader reader = this.typeReaders[index]; return this.ReadWithTypeReader(reader, null); } diff --git a/ANX.Framework/Content/GraphicTypeReaders/AlphaTestEffectReader.cs b/ANX.Framework/Content/GraphicTypeReaders/AlphaTestEffectReader.cs index 1f1fc4a6..aba85012 100644 --- a/ANX.Framework/Content/GraphicTypeReaders/AlphaTestEffectReader.cs +++ b/ANX.Framework/Content/GraphicTypeReaders/AlphaTestEffectReader.cs @@ -55,7 +55,7 @@ using ANX.Framework.Graphics; #endregion // License -namespace ANX.Framework.Content.GraphicTypeReaders +namespace ANX.Framework.Content { public class AlphaTestEffectReader : ContentTypeReader { diff --git a/ANX.Framework/Content/GraphicTypeReaders/BasicEffectReader.cs b/ANX.Framework/Content/GraphicTypeReaders/BasicEffectReader.cs index cc8fb458..15e24b7c 100644 --- a/ANX.Framework/Content/GraphicTypeReaders/BasicEffectReader.cs +++ b/ANX.Framework/Content/GraphicTypeReaders/BasicEffectReader.cs @@ -55,7 +55,7 @@ using ANX.Framework.Graphics; #endregion // License -namespace ANX.Framework.Content.GraphicTypeReaders +namespace ANX.Framework.Content { public class BasicEffectReader : ContentTypeReader { diff --git a/ANX.Framework/Content/GraphicTypeReaders/DualTextureEffectReader.cs b/ANX.Framework/Content/GraphicTypeReaders/DualTextureEffectReader.cs index 54f1f84e..7734f3ed 100644 --- a/ANX.Framework/Content/GraphicTypeReaders/DualTextureEffectReader.cs +++ b/ANX.Framework/Content/GraphicTypeReaders/DualTextureEffectReader.cs @@ -55,7 +55,7 @@ using ANX.Framework.Graphics; #endregion // License -namespace ANX.Framework.Content.GraphicTypeReaders +namespace ANX.Framework.Content { public class DualTextureEffectReader : ContentTypeReader { diff --git a/ANX.Framework/Content/GraphicTypeReaders/EffectMaterialReader.cs b/ANX.Framework/Content/GraphicTypeReaders/EffectMaterialReader.cs index 05d52d26..c7f8343a 100644 --- a/ANX.Framework/Content/GraphicTypeReaders/EffectMaterialReader.cs +++ b/ANX.Framework/Content/GraphicTypeReaders/EffectMaterialReader.cs @@ -55,7 +55,7 @@ using ANX.Framework.Graphics; #endregion // License -namespace ANX.Framework.Content.GraphicTypeReaders +namespace ANX.Framework.Content { public class EffectMaterialReader : ContentTypeReader { diff --git a/ANX.Framework/Content/GraphicTypeReaders/EnvironmentMapEffectReader.cs b/ANX.Framework/Content/GraphicTypeReaders/EnvironmentMapEffectReader.cs index 3a53ba53..5bdc2e51 100644 --- a/ANX.Framework/Content/GraphicTypeReaders/EnvironmentMapEffectReader.cs +++ b/ANX.Framework/Content/GraphicTypeReaders/EnvironmentMapEffectReader.cs @@ -55,7 +55,7 @@ using ANX.Framework.Graphics; #endregion // License -namespace ANX.Framework.Content.GraphicTypeReaders +namespace ANX.Framework.Content { public class EnvironmentMapEffectReader : ContentTypeReader { diff --git a/ANX.Framework/Content/GraphicTypeReaders/ModelReader.cs b/ANX.Framework/Content/GraphicTypeReaders/ModelReader.cs index eae656ca..24e94839 100644 --- a/ANX.Framework/Content/GraphicTypeReaders/ModelReader.cs +++ b/ANX.Framework/Content/GraphicTypeReaders/ModelReader.cs @@ -56,7 +56,7 @@ using ANX.Framework.NonXNA; #endregion // License -namespace ANX.Framework.Content.GraphicTypeReaders +namespace ANX.Framework.Content { public class ModelReader : ContentTypeReader { @@ -90,7 +90,7 @@ namespace ANX.Framework.Content.GraphicTypeReaders ModelBone[] bones = new ModelBone[boneCount]; for (int i = 0; i < boneCount; i++) { - string name = reader.ReadString(); + string name = reader.ReadObject(); Matrix transform = reader.ReadMatrix(); bones[i] = new ModelBone(name, transform, i); } @@ -123,14 +123,14 @@ namespace ANX.Framework.Content.GraphicTypeReaders { index = (int)reader.ReadInt32(); } - return index; + return index - 1; } private ModelBone ReadBoneReference(ContentReader reader, ModelBone[] bones) { ModelBone reference = null; int index = ReadBoneIndex(reader, bones.Length); - if (index != 0) + if (index >= 0 && index < bones.Length) { reference = bones[index]; } @@ -141,7 +141,7 @@ namespace ANX.Framework.Content.GraphicTypeReaders { ModelBone reference = null; int index = ReadBoneIndex(reader, bones.Count); - if (index != 0) + if (index >= 0) { reference = bones[index]; } @@ -154,9 +154,11 @@ namespace ANX.Framework.Content.GraphicTypeReaders ModelMesh[] meshes = new ModelMesh[meshCount]; for (int i = 0; i < meshCount; i++) { - string name = reader.ReadString(); + string name = reader.ReadObject(); ModelBone parentBone = ReadBoneReference(reader, bones); - BoundingSphere boundingSphere = reader.ReadObject(); + BoundingSphere boundingSphere = new BoundingSphere(); + boundingSphere.Center = reader.ReadVector3(); + boundingSphere.Radius = reader.ReadSingle(); object meshTag = reader.ReadObject(); int meshPartCount = reader.ReadInt32(); diff --git a/ANX.Framework/Content/GraphicTypeReaders/SkinnedEffectReader.cs b/ANX.Framework/Content/GraphicTypeReaders/SkinnedEffectReader.cs index 5ed43194..7c05c770 100644 --- a/ANX.Framework/Content/GraphicTypeReaders/SkinnedEffectReader.cs +++ b/ANX.Framework/Content/GraphicTypeReaders/SkinnedEffectReader.cs @@ -55,7 +55,7 @@ using ANX.Framework.Graphics; #endregion // License -namespace ANX.Framework.Content.GraphicTypeReaders +namespace ANX.Framework.Content { public class SkinnedEffectReader : ContentTypeReader { diff --git a/ANX.Framework/Content/GraphicTypeReaders/TextureCubeReader.cs b/ANX.Framework/Content/GraphicTypeReaders/TextureCubeReader.cs index ba820915..e8979f38 100644 --- a/ANX.Framework/Content/GraphicTypeReaders/TextureCubeReader.cs +++ b/ANX.Framework/Content/GraphicTypeReaders/TextureCubeReader.cs @@ -54,7 +54,7 @@ using ANX.Framework.NonXNA; #endregion // License -namespace ANX.Framework.Content.GraphicTypeReaders +namespace ANX.Framework.Content { internal class TextureCubeReader : ContentTypeReader { diff --git a/ANX.Framework/Content/GraphicTypeReaders/VertexBufferReader.cs b/ANX.Framework/Content/GraphicTypeReaders/VertexBufferReader.cs index ebac962f..8e4420bb 100644 --- a/ANX.Framework/Content/GraphicTypeReaders/VertexBufferReader.cs +++ b/ANX.Framework/Content/GraphicTypeReaders/VertexBufferReader.cs @@ -60,7 +60,7 @@ namespace ANX.Framework.Content protected internal override VertexBuffer Read(ContentReader input, VertexBuffer existingInstance) { GraphicsDevice graphics = input.ResolveGraphicsDevice(); - VertexDeclaration declaration = input.ReadObject(); + VertexDeclaration declaration = input.ReadRawObject(); int vertexCount = input.ReadInt32(); byte[] data = new byte[vertexCount * declaration.VertexStride]; for (int i = 0; i < data.Length; i++) diff --git a/ANX.Framework/Graphics/BasicEffect.cs b/ANX.Framework/Graphics/BasicEffect.cs index 958ebba1..9161aa20 100644 --- a/ANX.Framework/Graphics/BasicEffect.cs +++ b/ANX.Framework/Graphics/BasicEffect.cs @@ -84,11 +84,12 @@ namespace ANX.Framework.Graphics { get { - throw new NotImplementedException(); + return false; + //throw new NotImplementedException(); } set { - throw new NotImplementedException(); + //throw new NotImplementedException(); } } @@ -137,11 +138,12 @@ namespace ANX.Framework.Graphics { get { - throw new NotImplementedException(); + return Vector3.One; + //throw new NotImplementedException(); } set { - throw new NotImplementedException(); + //throw new NotImplementedException(); } } @@ -164,11 +166,12 @@ namespace ANX.Framework.Graphics { get { - throw new NotImplementedException(); + return false; + //throw new NotImplementedException(); } set { - throw new NotImplementedException(); + //throw new NotImplementedException(); } } @@ -176,11 +179,12 @@ namespace ANX.Framework.Graphics { get { - throw new NotImplementedException(); + return Vector3.One; + //throw new NotImplementedException(); } set { - throw new NotImplementedException(); + //throw new NotImplementedException(); } } @@ -188,11 +192,12 @@ namespace ANX.Framework.Graphics { get { - throw new NotImplementedException(); + return false; + //throw new NotImplementedException(); } set { - throw new NotImplementedException(); + //throw new NotImplementedException(); } } @@ -200,11 +205,12 @@ namespace ANX.Framework.Graphics { get { - throw new NotImplementedException(); + return 0; + //throw new NotImplementedException(); } set { - throw new NotImplementedException(); + //throw new NotImplementedException(); } } @@ -212,11 +218,12 @@ namespace ANX.Framework.Graphics { get { - throw new NotImplementedException(); + return 0; + //throw new NotImplementedException(); } set { - throw new NotImplementedException(); + //throw new NotImplementedException(); } } @@ -224,11 +231,12 @@ namespace ANX.Framework.Graphics { get { - throw new NotImplementedException(); + return null; + //throw new NotImplementedException(); } set { - throw new NotImplementedException(); + //throw new NotImplementedException(); } } @@ -236,11 +244,12 @@ namespace ANX.Framework.Graphics { get { - throw new NotImplementedException(); + return false; + //throw new NotImplementedException(); } set { - throw new NotImplementedException(); + //throw new NotImplementedException(); } } @@ -248,11 +257,12 @@ namespace ANX.Framework.Graphics { get { - throw new NotImplementedException(); + return Vector3.One; + //throw new NotImplementedException(); } set { - throw new NotImplementedException(); + //throw new NotImplementedException(); } } @@ -260,11 +270,12 @@ namespace ANX.Framework.Graphics { get { - throw new NotImplementedException(); + return Vector3.One; + //throw new NotImplementedException(); } set { - throw new NotImplementedException(); + //throw new NotImplementedException(); } } @@ -272,11 +283,12 @@ namespace ANX.Framework.Graphics { get { - throw new NotImplementedException(); + return Vector3.One; + //throw new NotImplementedException(); } set { - throw new NotImplementedException(); + //throw new NotImplementedException(); } } @@ -284,11 +296,12 @@ namespace ANX.Framework.Graphics { get { - throw new NotImplementedException(); + return 16; + //throw new NotImplementedException(); } set { - throw new NotImplementedException(); + //throw new NotImplementedException(); } } @@ -296,11 +309,12 @@ namespace ANX.Framework.Graphics { get { - throw new NotImplementedException(); + return 1; + //throw new NotImplementedException(); } set { - throw new NotImplementedException(); + //throw new NotImplementedException(); } } @@ -332,7 +346,8 @@ namespace ANX.Framework.Graphics return; } - throw new InvalidOperationException("Currently ANX's BasicEffect only supports VertexColor technique"); + this.CurrentTechnique = Techniques["VertexColor"]; + //throw new InvalidOperationException("Currently ANX's BasicEffect only supports VertexColor technique"); } } } diff --git a/ANX.Framework/Graphics/EffectPassCollection.cs b/ANX.Framework/Graphics/EffectPassCollection.cs index 4a5d948a..ff8b6f0c 100644 --- a/ANX.Framework/Graphics/EffectPassCollection.cs +++ b/ANX.Framework/Graphics/EffectPassCollection.cs @@ -101,17 +101,17 @@ namespace ANX.Framework.Graphics IEnumerator IEnumerable.GetEnumerator() { - throw new NotImplementedException(); + return (IEnumerator)this.passes.GetEnumerator(); } IEnumerator IEnumerable.GetEnumerator() { - throw new NotImplementedException(); + return (IEnumerator)this.passes.GetEnumerator(); } public List.Enumerator GetEnumerator() { - throw new NotImplementedException(); + return this.passes.GetEnumerator(); } public int Count diff --git a/ANX.Framework/Graphics/Model.cs b/ANX.Framework/Graphics/Model.cs index 0e4d3030..737561e9 100644 --- a/ANX.Framework/Graphics/Model.cs +++ b/ANX.Framework/Graphics/Model.cs @@ -83,6 +83,8 @@ namespace ANX.Framework.Graphics set { tag = value; } } + private static Matrix[] cachedBonesArray; + public Model(ModelBoneCollection bones, ModelMeshCollection meshes, ModelBone rootBone, Object tag) { this.bones = bones; @@ -93,22 +95,92 @@ namespace ANX.Framework.Graphics public void CopyAbsoluteBoneTransformsTo(Matrix[] destinationBoneTransforms) { - throw new NotImplementedException(); + if (destinationBoneTransforms == null) + { + throw new ArgumentNullException("destinationBoneTransforms"); + } + + if (destinationBoneTransforms.Length < bones.Count) + { + throw new ArgumentOutOfRangeException("destinationBoneTransforms"); + } + + for (int i = 0; i < bones.Count; i++) + { + var bone = bones[i]; + if (bone.Parent == null) + { + destinationBoneTransforms[i] = bone.Transform; + } + else + { + int parentIndex = bone.Parent.Index; + destinationBoneTransforms[i] = bone.Transform * destinationBoneTransforms[parentIndex]; + } + } } public void CopyBoneTransformsFrom(Matrix[] sourceBoneTransforms) { - throw new NotImplementedException(); + if (sourceBoneTransforms == null) + { + throw new ArgumentNullException("sourceBoneTransforms"); + } + + if (sourceBoneTransforms.Length < bones.Count) + { + throw new ArgumentOutOfRangeException("sourceBoneTransforms"); + } + + for (int i = 0; i < bones.Count; i++) + { + bones[i].Transform = sourceBoneTransforms[i]; + } } public void CopyBoneTransformsTo(Matrix[] destinationBoneTransforms) { - throw new NotImplementedException(); + if (destinationBoneTransforms == null) + { + throw new ArgumentNullException("destinationBoneTransforms"); + } + + if (destinationBoneTransforms.Length < bones.Count) + { + throw new ArgumentOutOfRangeException("destinationBoneTransforms"); + } + + for (int i = 0; i < bones.Count; i++) + { + destinationBoneTransforms[i] = bones[i].Transform; + } } public void Draw (Matrix world, Matrix view, Matrix projection) { - throw new NotImplementedException(); + Matrix[] absTransforms = Model.cachedBonesArray; + if (absTransforms == null || absTransforms.Length < this.bones.Count) + { + Array.Resize(ref absTransforms, this.bones.Count); + Model.cachedBonesArray = absTransforms; + } + this.CopyAbsoluteBoneTransformsTo(absTransforms); + + foreach (var mesh in meshes) + { + foreach (var effect in mesh.Effects) + { + IEffectMatrices matEffect = effect as IEffectMatrices; + if (matEffect != null) + { + matEffect.World = absTransforms[mesh.ParentBone.Index] * world; + matEffect.View = view; + matEffect.Projection = projection; + } + } + + mesh.Draw(); + } } } } diff --git a/ANX.Framework/Graphics/ModelEffectCollection.cs b/ANX.Framework/Graphics/ModelEffectCollection.cs index 8b92c7c4..16ed8b0c 100644 --- a/ANX.Framework/Graphics/ModelEffectCollection.cs +++ b/ANX.Framework/Graphics/ModelEffectCollection.cs @@ -57,12 +57,12 @@ namespace ANX.Framework.Graphics { public sealed class ModelEffectCollection : ReadOnlyCollection { - private Effect[] effects; + private List effects; - internal ModelEffectCollection(Effect[] effects) - : base(effects) + internal ModelEffectCollection() + : base(new List()) { - this.effects = effects; + this.effects = base.Items as List; } public new Enumerator GetEnumerator() @@ -70,12 +70,22 @@ namespace ANX.Framework.Graphics return new Enumerator(this.effects); } + public void Add(Effect effect) + { + base.Items.Add(effect); + } + + public void Remove(Effect effect) + { + base.Items.Remove(effect); + } + public struct Enumerator : IEnumerator, IDisposable, IEnumerator { - private Effect[] wrappedArray; + private List wrappedArray; private int position; - internal Enumerator(Effect[] wrappedArray) + internal Enumerator(List wrappedArray) { this.wrappedArray = wrappedArray; this.position = -1; @@ -92,9 +102,9 @@ namespace ANX.Framework.Graphics public bool MoveNext() { this.position++; - if (this.position >= this.wrappedArray.Length) + if (this.position >= this.wrappedArray.Count) { - this.position = this.wrappedArray.Length; + this.position = this.wrappedArray.Count; return false; } return true; diff --git a/ANX.Framework/Graphics/ModelMesh.cs b/ANX.Framework/Graphics/ModelMesh.cs index 8eba6a39..c6fe03b0 100644 --- a/ANX.Framework/Graphics/ModelMesh.cs +++ b/ANX.Framework/Graphics/ModelMesh.cs @@ -105,11 +105,66 @@ namespace ANX.Framework.Graphics this.boundingSphere = sphere; this.tag = tag; this.meshParts = new ModelMeshPartCollection(meshParts); + this.effects = new ModelEffectCollection(); + + foreach (var item in this.meshParts) + { + item.parentMesh = this; + if (item.Effect != null && !this.effects.Contains(item.Effect)) + { + this.effects.Add(item.Effect); + } + } + } + + internal void EffectChangedOnMeshPart(ModelMeshPart part, Effect oldEffect, Effect newEffect) + { + bool oldEffectIsInUse = false; + bool newEffectIsKnown = false; + + foreach (var item in meshParts) + { + if (object.ReferenceEquals(item, part)) + { + continue; + } + + if (object.ReferenceEquals(item.Effect, oldEffect)) + { + oldEffectIsInUse = true; + } + + if (object.ReferenceEquals(item.Effect, newEffect)) + { + newEffectIsKnown = true; + } + } + + if (oldEffect != null && !oldEffectIsInUse) + { + effects.Remove(oldEffect); + } + + if (newEffect != null && !newEffectIsKnown) + { + effects.Add(oldEffect); + } } public void Draw() { - throw new NotImplementedException(); + foreach (var part in meshParts) + { + foreach (var pass in part.Effect.CurrentTechnique.Passes) + { + pass.Apply(); + + GraphicsDevice graphics = part.VertexBuffer.GraphicsDevice; + graphics.SetVertexBuffer(part.VertexBuffer, part.VertexOffset); + graphics.Indices = part.IndexBuffer; + graphics.DrawIndexedPrimitives(PrimitiveType.TriangleList, 0, 0, part.NumVertices, part.StartIndex, part.PrimitiveCount); + } + } } } } diff --git a/ANX.Framework/Graphics/ModelMeshPart.cs b/ANX.Framework/Graphics/ModelMeshPart.cs index efd6da28..a6c6d69b 100644 --- a/ANX.Framework/Graphics/ModelMeshPart.cs +++ b/ANX.Framework/Graphics/ModelMeshPart.cs @@ -54,12 +54,22 @@ namespace ANX.Framework.Graphics { public sealed class ModelMeshPart { + internal ModelMesh parentMesh; + private Effect effect; public Effect Effect { get { return effect; } - set { this.effect = value; } + set + { + if (this.effect != value) + { + var old = this.effect; + this.effect = value; + this.parentMesh.EffectChangedOnMeshPart(this, old, value); + } + } } private IndexBuffer indexBuffer;