public static void ComputeTangents(MeshGeometry3D meshGeometry)
 {
     Vector3Collection t1, t2;
     ComputeTangents(meshGeometry.Positions, meshGeometry.Normals, meshGeometry.TextureCoordinates, meshGeometry.Indices, out t1, out t2);
     meshGeometry.Tangents = t1;
     meshGeometry.BiTangents = t2;
 }
        /// <summary>
        /// Appends the specified mesh.
        /// </summary>
        /// <param name="mesh">
        /// The mesh.
        /// </param>
        public void Append(MeshGeometry3D mesh)
        {
            if (mesh == null)
            {
                throw new ArgumentNullException("mesh");
            }

            this.Append(mesh.Positions, mesh.Indices, mesh.Normals, mesh.TextureCoordinates);
        }
        public override void Attach(IRenderHost host)
        {
            /// --- attach
            this.renderTechnique = host.RenderTechniquesManager.RenderTechniques[DefaultRenderTechniqueNames.CubeMap];
            base.Attach(host);

            /// --- get variables
            this.vertexLayout = renderHost.EffectsManager.GetLayout(this.renderTechnique);
            this.effectTechnique = effect.GetTechniqueByName(this.renderTechnique.Name);
            this.effectTransforms = new EffectTransformVariables(this.effect);

            /// -- attach cube map
            if (this.Filename != null)
            {
                /// -- attach texture
                using (var texture = Texture2D.FromFile<Texture2D>(this.Device, this.Filename))
                {
                    this.texCubeMapView = new ShaderResourceView(this.Device, texture);
                }
                this.texCubeMap = effect.GetVariableByName("texCubeMap").AsShaderResource();
                this.texCubeMap.SetResource(this.texCubeMapView);
                this.bHasCubeMap = effect.GetVariableByName("bHasCubeMap").AsScalar();
                this.bHasCubeMap.Set(true);

                /// --- set up geometry
                var sphere = new MeshBuilder(false,true,false);
                sphere.AddSphere(new Vector3(0, 0, 0));
                this.geometry = sphere.ToMeshGeometry3D();

                /// --- set up vertex buffer
                this.vertexBuffer = Device.CreateBuffer(BindFlags.VertexBuffer, CubeVertex.SizeInBytes, this.geometry.Positions.Select((x, ii) => new CubeVertex() { Position = new Vector4(x, 1f) }).ToArray());

                /// --- set up index buffer
                this.indexBuffer = Device.CreateBuffer(BindFlags.IndexBuffer, sizeof(int), geometry.Indices.Array);

                /// --- set up rasterizer states
                var rasterStateDesc = new RasterizerStateDescription()
                {
                    FillMode = FillMode.Solid,
                    CullMode = CullMode.Back,
                    IsMultisampleEnabled = true,
                    IsAntialiasedLineEnabled = true,
                    IsFrontCounterClockwise = false,
                };
                this.rasterState = new RasterizerState(this.Device, rasterStateDesc);

                /// --- set up depth stencil state
                var depthStencilDesc = new DepthStencilStateDescription()
                {
                    DepthComparison = Comparison.LessEqual,
                    DepthWriteMask = global::SharpDX.Direct3D11.DepthWriteMask.All,
                    IsDepthEnabled = true,
                };
                this.depthStencilState = new DepthStencilState(this.Device, depthStencilDesc);
            }

            /// --- flush
            this.Device.ImmediateContext.Flush();
        }
        public static MeshGeometry3D Merge(params MeshGeometry3D[] meshes)
        {
            var positions = new Vector3Collection();
            var indices = new IntCollection();

            var normals = meshes.All(x => x.Normals != null) ? new Vector3Collection() : null;
            var colors = meshes.All(x => x.Colors != null) ? new Color4Collection() : null;
            var textureCoods = meshes.All(x => x.TextureCoordinates != null) ? new Vector2Collection() : null;
            var tangents = meshes.All(x => x.Tangents != null) ? new Vector3Collection() : null;
            var bitangents = meshes.All(x => x.BiTangents != null) ? new Vector3Collection() : null;

            int index = 0;
            foreach (var part in meshes)
            {
                for (int i = 0; i < part.Positions.Count; i++)
                {
                    positions.Add(part.Positions[i]);
                }

                for (int i = 0; i < part.Indices.Count; i++)
                {
                    indices.Add(index + part.Indices[i]);
                }

                index += part.Indices.Count;
            }

            if (normals != null)
            {
                normals = new Vector3Collection(meshes.SelectMany(x => x.Normals));
            }

            if (colors != null)
            {
                colors = new Color4Collection(meshes.SelectMany(x => x.Colors));
            }

            if (textureCoods != null)
            {
                textureCoods = new Vector2Collection(meshes.SelectMany(x => x.TextureCoordinates));
            }

            if (tangents != null)
            {
                tangents = new Vector3Collection(meshes.SelectMany(x => x.Tangents));
            }

            if (bitangents != null)
            {
                bitangents = new Vector3Collection(meshes.SelectMany(x => x.BiTangents));
            }

            var mesh = new MeshGeometry3D()
            {
                Positions = positions,
                Indices = indices,
            };

            mesh.Normals = normals;
            mesh.Colors = colors;
            mesh.TextureCoordinates = textureCoods;
            mesh.Tangents = tangents;
            mesh.BiTangents = bitangents;

            return mesh;
        }
        public override void Detach()
        {
            if (!this.IsAttached)
                return;

            this.bHasCubeMap.Set(false);

            this.effectTechnique = null;
            this.effectTechnique = null;
            this.vertexLayout = null;
            this.geometry = null;

            Disposer.RemoveAndDispose(ref this.vertexBuffer);
            Disposer.RemoveAndDispose(ref this.indexBuffer);
            Disposer.RemoveAndDispose(ref this.texCubeMap);
            Disposer.RemoveAndDispose(ref this.texCubeMapView);
            Disposer.RemoveAndDispose(ref this.bHasCubeMap);
            Disposer.RemoveAndDispose(ref this.rasterState);
            Disposer.RemoveAndDispose(ref this.depthStencilState);
            Disposer.RemoveAndDispose(ref this.effectTransforms);

            base.Detach();
        }