Example #1
0
        /// <summary>
        /// Creates a render request for the model using the specified transform.
        /// </summary>
        /// <param name="renderContext">
        ///     The render context.
        /// </param>
        /// <param name="effect"></param>
        /// <param name="effectParameterSet"></param>
        /// <param name="transform">
        ///     The transform.
        /// </param>
        public IRenderRequest CreateRenderRequest(IRenderContext renderContext, IEffect effect, IEffectParameterSet effectParameterSet, Matrix transform)
        {
            if (Vertexes.Length == 0 && Indices.Length == 0)
            {
                throw new InvalidOperationException(
                          "This model does not have any vertexes or indices.  It's most " +
                          "likely been imported from an FBX file that only contains hierarchy, " +
                          "in which case there isn't anything to render.");
            }

            LoadBuffers(renderContext.GraphicsDevice);

            VertexBuffer vertexBuffer;

            if (_cachedVertexBuffers.ContainsKey(effect))
            {
                vertexBuffer = _cachedVertexBuffers[effect];
            }
            else
            {
                // Find the vertex mapping configuration for this model.
                if (_cachedModelVertexMapping == null)
                {
                    _cachedModelVertexMapping =
                        _modelRenderConfigurations.Select(x => x.GetVertexMappingToGPU(this, effect))
                        .FirstOrDefault(x => x != null);
                    if (_cachedModelVertexMapping == null)
                    {
                        throw new InvalidOperationException(
                                  "No implementation of IModelRenderConfiguration could provide a vertex " +
                                  "mapping for this model.  You must implement IModelRenderConfiguration " +
                                  "and bind it in the dependency injection system, so that the engine is " +
                                  "aware of how to map vertices in models to parameters in effects.");
                    }
                }

                var mappedVerticies = Array.CreateInstance(_cachedModelVertexMapping.VertexType, Vertexes.Length);
                for (var i = 0; i < Vertexes.Length; i++)
                {
                    var vertex = _cachedModelVertexMapping.MappingFunction(Vertexes[i]);
                    mappedVerticies.SetValue(vertex, i);
                }

                float maxX = 0f, maxY = 0f, maxZ = 0f;
                foreach (var vert in this.Vertexes)
                {
                    if (vert.Position.HasValue)
                    {
                        if (Math.Abs(vert.Position.Value.X) > maxX)
                        {
                            maxX = Math.Abs(vert.Position.Value.X);
                        }
                        if (Math.Abs(vert.Position.Value.Y) > maxY)
                        {
                            maxY = Math.Abs(vert.Position.Value.Y);
                        }
                        if (Math.Abs(vert.Position.Value.Z) > maxZ)
                        {
                            maxZ = Math.Abs(vert.Position.Value.Z);
                        }
                    }
                }

                var radius = new Vector3(maxX, maxY, maxZ).Length() * 2;

                _localisedBoundingRegion = new LocalisedBoundingRegion(radius);

                vertexBuffer = new VertexBuffer(
                    renderContext.GraphicsDevice,
                    _cachedModelVertexMapping.VertexDeclaration,
                    Vertexes.Length,
                    BufferUsage.WriteOnly);
                vertexBuffer.GetType().GetMethods().First(x => x.Name == "SetData" && x.GetParameters().Length == 1).MakeGenericMethod(_cachedModelVertexMapping.VertexType).Invoke(
                    vertexBuffer,
                    new[] { mappedVerticies });
                _cachedVertexBuffers[effect] = vertexBuffer;
            }

            if (effectParameterSet.HasSemantic <IBonesEffectSemantic>())
            {
                var bonesEffectSemantic = effectParameterSet.GetSemantic <IBonesEffectSemantic>();

                foreach (var bone in _flattenedBones)
                {
                    if (bone.ID == -1)
                    {
                        continue;
                    }

                    bonesEffectSemantic.Bones[bone.ID] = bone.GetFinalMatrix();
                }
            }

            // Create the render request.
            return(_renderBatcher.CreateSingleRequestFromState(
                       renderContext,
                       effect,
                       effectParameterSet,
                       vertexBuffer,
                       IndexBuffer,
                       PrimitiveType.TriangleList,
                       renderContext.World * transform, (m, vb, ib) =>
            {
                var mappedVerticies = Array.CreateInstance(_cachedModelVertexMapping.VertexType, Vertexes.Length * m.Count);
                var mappedIndicies = new int[Indices.Length * m.Count];

                for (var im = 0; im < m.Count; im++)
                {
                    for (var i = 0; i < Vertexes.Length; i++)
                    {
                        var vertex = _cachedModelVertexMapping.MappingFunction(Vertexes[i].Transform(m[im]));
                        mappedVerticies.SetValue(vertex, im * Vertexes.Length + i);
                    }

                    for (var i = 0; i < Indices.Length; i++)
                    {
                        mappedIndicies[im * Vertexes.Length + i] = Indices[i] + Vertexes.Length * im;
                    }
                }

                vb.GetType().GetMethods().First(x => x.Name == "SetData" && x.GetParameters().Length == 1).MakeGenericMethod(_cachedModelVertexMapping.VertexType).Invoke(
                    vb,
                    new[] { mappedVerticies });
                ib.SetData(mappedIndicies);
            },
                       _localisedBoundingRegion));
        }
        public void RenderCube(IRenderContext context, IEffect effect, IEffectParameterSet effectParameterSet, Matrix transform, Color color)
        {
            if (!context.IsCurrentRenderPass <I3DRenderPass>())
            {
                throw new InvalidOperationException("Can't use 3D rendering utilities in 2D context.");
            }

            var vertexes = _renderCache.GetOrSet(
                "rendercube3dvb:" + color,
                () =>
            {
                var vb = new VertexBuffer(context.GraphicsDevice, VertexPositionNormalColor.VertexDeclaration, 24, BufferUsage.WriteOnly);
                vb.SetData(new[]
                {
                    new VertexPositionNormalColor(new Vector3(0, 0, 0), new Vector3(-1, 0, 0), color),
                    new VertexPositionNormalColor(new Vector3(0, 0, 1), new Vector3(-1, 0, 0), color),
                    new VertexPositionNormalColor(new Vector3(0, 1, 0), new Vector3(-1, 0, 0), color),
                    new VertexPositionNormalColor(new Vector3(0, 1, 1), new Vector3(-1, 0, 0), color),

                    new VertexPositionNormalColor(new Vector3(1, 0, 0), new Vector3(1, 0, 0), color),
                    new VertexPositionNormalColor(new Vector3(1, 0, 1), new Vector3(1, 0, 0), color),
                    new VertexPositionNormalColor(new Vector3(1, 1, 0), new Vector3(1, 0, 0), color),
                    new VertexPositionNormalColor(new Vector3(1, 1, 1), new Vector3(1, 0, 0), color),

                    new VertexPositionNormalColor(new Vector3(0, 0, 0), new Vector3(0, -1, 0), color),
                    new VertexPositionNormalColor(new Vector3(0, 0, 1), new Vector3(0, -1, 0), color),
                    new VertexPositionNormalColor(new Vector3(0, 1, 0), new Vector3(0, 1, 0), color),
                    new VertexPositionNormalColor(new Vector3(0, 1, 1), new Vector3(0, 1, 0), color),

                    new VertexPositionNormalColor(new Vector3(1, 0, 0), new Vector3(0, -1, 0), color),
                    new VertexPositionNormalColor(new Vector3(1, 0, 1), new Vector3(0, -1, 0), color),
                    new VertexPositionNormalColor(new Vector3(1, 1, 0), new Vector3(0, 1, 0), color),
                    new VertexPositionNormalColor(new Vector3(1, 1, 1), new Vector3(0, 1, 0), color),

                    new VertexPositionNormalColor(new Vector3(0, 0, 0), new Vector3(0, 0, -1), color),
                    new VertexPositionNormalColor(new Vector3(0, 0, 1), new Vector3(0, 0, 1), color),
                    new VertexPositionNormalColor(new Vector3(0, 1, 0), new Vector3(0, 0, -1), color),
                    new VertexPositionNormalColor(new Vector3(0, 1, 1), new Vector3(0, 0, 1), color),

                    new VertexPositionNormalColor(new Vector3(1, 0, 0), new Vector3(0, 0, -1), color),
                    new VertexPositionNormalColor(new Vector3(1, 0, 1), new Vector3(0, 0, 1), color),
                    new VertexPositionNormalColor(new Vector3(1, 1, 0), new Vector3(0, 0, -1), color),
                    new VertexPositionNormalColor(new Vector3(1, 1, 1), new Vector3(0, 0, 1), color)
                });
                return(vb);
            });
            var indicies = _renderCache.GetOrSet(
                "rendercube3dib",
                () =>
            {
                var ib = new IndexBuffer(context.GraphicsDevice, IndexElementSize.SixteenBits, 36, BufferUsage.WriteOnly);
                ib.SetData(new short[]
                {
                    0, 2, 1,
                    3, 1, 2,

                    4, 5, 6,
                    7, 6, 5,

                    0 + 8, 1 + 8, 4 + 8,
                    5 + 8, 4 + 8, 1 + 8,

                    2 + 8, 6 + 8, 3 + 8,
                    7 + 8, 3 + 8, 6 + 8,

                    0 + 16, 4 + 16, 2 + 16,
                    6 + 16, 2 + 16, 4 + 16,

                    1 + 16, 3 + 16, 5 + 16,
                    7 + 16, 5 + 16, 3 + 16
                });
                return(ib);
            });

            _renderBatcher.QueueRequest(
                context,
                _renderBatcher.CreateSingleRequestFromState(
                    context,
                    effect,
                    effectParameterSet,
                    vertexes,
                    indicies,
                    PrimitiveType.TriangleList,
                    transform,
                    null));
        }