i cant transforme a 2d pickture to 3d

Started by
7 comments, last by Pedro Alves 9 years, 8 months ago

i have this error unhandled exception of type 'Microsoft.Xna.Framework.Content.ContentLoadException' occurred in Microsoft.Xna.Framework.dll

Additional information: Error loading "terrain". File contains Microsoft.Xna.Framework.Graphics.Texture2D but trying to load as Microsoft.Xna.Framework.Graphics.Model.

i use to make this code this example http://xbox.create.msdn.com/en-US/education/catalog/sample/collision_3d_heightmap

this is my code


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.GamerServices;
using TomShane.Neoforce.Controls;
using XRpgLibrary;
using System.Threading;
using System.Security.Cryptography;
using System.Security;
using Microsoft.Xna.Framework.Input;

namespace TomShane.Neoforce.Central.Code
{
    public class Gameplays : BaseGameState
    {
        const float SphereVelocity = 2;
        GraphicsDeviceManager graphics1;
        // how quickly the sphere can turn from side to side
        const float SphereTurnSpeed = .025f;

        // the radius of the sphere. We'll use this to keep the sphere above the ground,
        // and when computing how far the sphere has rolled.
        const float SphereRadius = 12.0f;

        // This vector controls how much the camera's position is offset from the
        // sphere. This value can be changed to move the camera further away from or
        // closer to the sphere.
        readonly Vector3 CameraPositionOffset = new Vector3(0, 40, 150);

        // This value controls the point the camera will aim at. This value is an offset
        // from the sphere's position.
        readonly Vector3 CameraTargetOffset = new Vector3(0, 30, 0);
        string text = "admin";
         string texto;
        private Label lbusername = null;
        private Manager NeoManager;

        Model terrain;

        Matrix projectionMatrix;
        Matrix viewMatrix;

        Vector3 spherePosition;
        float sphereFacingDirection;
        Matrix sphereRollingMatrix = Matrix.Identity;

        Model sphere;
        HeightMapInfo heightMapInfo;
        public Gameplays(Game game, GameStateManager manager, GraphicsDeviceManager graphics)
            : base(game, manager)
        {
           
            NeoManager = new Manager(game, graphics, "Default");
            graphics1 = graphics;
            //graphics = new GraphicsDeviceManager(Game);
            NeoManager.SkinDirectory = @"C:\Users\Pedro\Dropbox\GAMES\TomShane.Neoforce.Controls.XNA4\Neoforce\Skins";
            NeoManager.AutoUnfocus = false;
           texto = text;
            System.Console.Write(texto);

           

        }
        protected override void LoadContent()
        {



            terrain = Game.Content.Load<Model>("terrain");//error is where

            // The terrain processor attached a HeightMapInfo to the terrain model's
            // Tag. We'll save that to a member variable now, and use it to
            // calculate the terrain's heights later.
            heightMapInfo = terrain.Tag as HeightMapInfo;
            if (heightMapInfo == null)
            {
                string message = "The terrain model did not have a HeightMapInfo " +
                    "object attached. Are you sure you are using the " +
                    "TerrainProcessor?";
                throw new InvalidOperationException(message);
            }

            sphere = Game.Content.Load<Model>("sphere");
            base.LoadContent();


            InitConsole(texto);


            // NeoManager.Add(sidebar);









        }
        public override void Update(GameTime gameTime)
        {
            HandleInput();

            UpdateCamera();
           // StateManager.Update(gameTime);
            //  ControlManager.Update(gameTime, PlayerIndex.One);
            base.Update(gameTime);

            NeoManager.Update(gameTime);
            //   stateManager.PopState();
        }
        public override void Draw(GameTime gameTime)
        {
            //  StateManager.BeginDraw(gameTime);
            NeoManager.BeginDraw(gameTime);

            GraphicsDevice.Clear(Color.CornflowerBlue);

            NeoManager.EndDraw();
            DrawModel(terrain, Matrix.Identity);

            DrawModel(sphere, sphereRollingMatrix *
                Matrix.CreateTranslation(spherePosition));
            //   ControlManager.Draw(GameRef.spriteBatch);
            base.Draw(gameTime);


        }
        void DrawModel(Model model, Matrix worldMatrix)
        {
            Matrix[] boneTransforms = new Matrix[model.Bones.Count];
            model.CopyAbsoluteBoneTransformsTo(boneTransforms);

            foreach (ModelMesh mesh in model.Meshes)
            {
                foreach (BasicEffect effect in mesh.Effects)
                {
                    effect.World = boneTransforms[mesh.ParentBone.Index] * worldMatrix;
                    effect.View = viewMatrix;
                    effect.Projection = projectionMatrix;

                    effect.EnableDefaultLighting();
                    effect.PreferPerPixelLighting = true;

                    // Set the fog to match the black background color
                    effect.FogEnabled = true;
                    effect.FogColor = Vector3.Zero;
                    effect.FogStart = 1000;
                    effect.FogEnd = 3200;
                }

                mesh.Draw();
            }
        }


      

       



        /// <summary>
        /// Handles input for quitting the game.
        /// </summary>
        private void HandleInput()
        {
            KeyboardState currentKeyboardState = Keyboard.GetState();
            GamePadState currentGamePadState = GamePad.GetState(PlayerIndex.One);

            // Check for exit.
           

            // Now move the sphere. First, we want to check to see if the sphere should
            // turn. turnAmount will be an accumulation of all the different possible
            // inputs.
            float turnAmount = -currentGamePadState.ThumbSticks.Left.X;
            if (currentKeyboardState.IsKeyDown(Keys.A) ||
                currentKeyboardState.IsKeyDown(Keys.Left) ||
                currentGamePadState.DPad.Left == ButtonState.Pressed)
            {
                turnAmount += 1;
            }
            if (currentKeyboardState.IsKeyDown(Keys.D) ||
                currentKeyboardState.IsKeyDown(Keys.Right) ||
                currentGamePadState.DPad.Right == ButtonState.Pressed)
            {
                turnAmount -= 1;
            }

            // clamp the turn amount between -1 and 1, and then use the finished
            // value to turn the sphere.
            turnAmount = MathHelper.Clamp(turnAmount, -1, 1);
            sphereFacingDirection += turnAmount * SphereTurnSpeed;


            // Next, we want to move the sphere forward or back. to do this, 
            // we'll create a Vector3 and modify use the user's input to modify the Z
            // component, which corresponds to the forward direction.
            Vector3 movement = Vector3.Zero;
            movement.Z = -currentGamePadState.ThumbSticks.Left.Y;

            if (currentKeyboardState.IsKeyDown(Keys.W) ||
                currentKeyboardState.IsKeyDown(Keys.Up) ||
                currentGamePadState.DPad.Up == ButtonState.Pressed)
            {
                movement.Z = -1;
            }
            if (currentKeyboardState.IsKeyDown(Keys.S) ||
                currentKeyboardState.IsKeyDown(Keys.Down) ||
                currentGamePadState.DPad.Down == ButtonState.Pressed)
            {
                movement.Z = 1;
            }

            // next, we'll create a rotation matrix from the sphereFacingDirection, and
            // use it to transform the vector. If we didn't do this, pressing "up" would
            // always move the ball along +Z. By transforming it, we can move in the
            // direction the sphere is "facing."
            Matrix sphereFacingMatrix = Matrix.CreateRotationY(sphereFacingDirection);
            Vector3 velocity = Vector3.Transform(movement, sphereFacingMatrix);
            velocity *= SphereVelocity;

            // Now we know how much the user wants to move. We'll construct a temporary
            // vector, newSpherePosition, which will represent where the user wants to
            // go. If that value is on the heightmap, we'll allow the move.
            Vector3 newSpherePosition = spherePosition + velocity;
            if (heightMapInfo.IsOnHeightmap(newSpherePosition))
            {
                // finally, we need to see how high the terrain is at the sphere's new
                // position. GetHeight will give us that information, which is offset by
                // the size of the sphere. If we didn't offset by the size of the
                // sphere, it would be drawn halfway through the world, which looks 
                // a little odd.
                newSpherePosition.Y = heightMapInfo.GetHeight(newSpherePosition) +
                    SphereRadius;
            }
            else
            {
                newSpherePosition = spherePosition;
            }

            // now we need to roll the ball "forward." to do this, we first calculate
            // how far it has moved.
            float distanceMoved = Vector3.Distance(spherePosition, newSpherePosition);

            // The length of an arc on a circle or sphere is defined as L = theta * r,
            // where theta is the angle that defines the arc, and r is the radius of
            // the circle.
            // we know L, that's the distance the sphere has moved. we know r, that's
            // our constant "sphereRadius". We want to know theta - that will tell us
            // how much to rotate the sphere. we rearrange the equation to get...
            float theta = distanceMoved / SphereRadius;

            // now that we know how much to rotate the sphere, we have to figure out 
            // whether it will roll forward or backward. We'll base this on the user's
            // input.
            int rollDirection = movement.Z > 0 ? 1 : -1;

            // finally, we'll roll it by rotating around the sphere's "right" vector.
            sphereRollingMatrix *= Matrix.CreateFromAxisAngle(sphereFacingMatrix.Right,
                theta * rollDirection);

            // once we've finished all computations, we can set spherePosition to the
            // new position that we calculated.
            spherePosition = newSpherePosition;
        }

     

        private void UpdateCamera()
        {
            // The camera's position depends on the sphere's facing direction: when the
            // sphere turns, the camera needs to stay behind it. So, we'll calculate a
            // rotation matrix using the sphere's facing direction, and use it to
            // transform the two offset values that control the camera.
            Matrix cameraFacingMatrix = Matrix.CreateRotationY(sphereFacingDirection);
            Vector3 positionOffset = Vector3.Transform(CameraPositionOffset,
                cameraFacingMatrix);
            Vector3 targetOffset = Vector3.Transform(CameraTargetOffset,
                cameraFacingMatrix);

            // once we've transformed the camera's position offset vector, it's easy to
            // figure out where we think the camera should be.
            Vector3 cameraPosition = spherePosition + positionOffset;

            // We don't want the camera to go beneath the heightmap, so if the camera is
            // over the terrain, we'll move it up.
            if (heightMapInfo.IsOnHeightmap(cameraPosition))
            {
                // we don't want the camera to go beneath the terrain's height +
                // a small offset.
                float minimumHeight =
                    heightMapInfo.GetHeight(cameraPosition) + CameraPositionOffset.Y;

                if (cameraPosition.Y < minimumHeight)
                {
                    cameraPosition.Y = minimumHeight;
                }
            }

            // next, we need to calculate the point that the camera is aiming it. That's
            // simple enough - the camera is aiming at the sphere, and has to take the 
            // targetOffset into account.
            Vector3 cameraTarget = spherePosition + targetOffset;


            // with those values, we'll calculate the viewMatrix.
            viewMatrix = Matrix.CreateLookAt(cameraPosition,
                                              cameraTarget,
                                              Vector3.Up);
        }
        public override void Initialize()
        {
            
            NeoManager.Initialize();
         //   StateManager.Initialize();
            base.Initialize();
            projectionMatrix = Matrix.CreatePerspectiveFieldOfView(
               MathHelper.ToRadians(45.0f), GraphicsDevice.Viewport.AspectRatio, 1f, 10000);
            //  NeoManager.Initialize();
        }
         private void InitConsole(string texto)
        {
            lbusername = new Label(NeoManager);

            TomShane.Neoforce.Controls.TabControl tbc = new TomShane.Neoforce.Controls.TabControl(NeoManager);
            TomShane.Neoforce.Controls.Console con1 = new TomShane.Neoforce.Controls.Console(NeoManager);
            TomShane.Neoforce.Controls.Console con2 = new TomShane.Neoforce.Controls.Console(NeoManager);
            //TomShane.Neoforce.Controls.Console con3 = new TomShane.Neoforce.Controls.Console(Manager);
            //Console con3 = new Console(Manager);

            // Setup of TabControl, which will be holding both consoles
            tbc.Init();
            tbc.AddPage("Global");
            tbc.AddPage("Guild");
            tbc.AddPage("PARTY");
            tbc.AddPage("TRADE");
            tbc.Alpha = 220;
            tbc.Left = 0;
            tbc.Height = 220;
            tbc.Width = 400;
            tbc.Top = NeoManager.TargetHeight - tbc.Height - 32;
            // tbc.Focused = fals;

            tbc.Movable = false;
            tbc.Resizable = false;
            tbc.MinimumHeight = 96;
            tbc.MinimumWidth = 160;

            tbc.TabPages[0].Add(con1);
            tbc.TabPages[1].Add(con2);

            //tbc.TabPages[2].Add(con3);

            con1.Init();
            con1.Sender = texto;
            con2.Init();
            //con3.Init();
            con2.Width = con1.Width = tbc.TabPages[0].ClientWidth;
            con2.Height = con1.Height = tbc.TabPages[0].ClientHeight;
            con2.Anchor = con1.Anchor = Anchors.All;
            con1.Channels.Add(new ConsoleChannel(0, "General", Color.Orange));
            con1.Channels.Add(new ConsoleChannel(1, "Private", Color.White));
            con1.Channels.Add(new ConsoleChannel(2, "System", Color.Yellow));
            con1.Channels.Add(new ConsoleChannel(3, "Guild", Color.Green));
            con1.Channels.Add(new ConsoleChannel(4, "Trade", Color.Red));
            // We want to share channels and message buffer in both consoles
            con2.Channels = con1.Channels;
            con2.MessageBuffer = con1.MessageBuffer;

            // In the second console we display only "Private" messages
            con2.ChannelFilter.Add(3);

            // Select default channels for each tab
            con1.SelectedChannel = 0;
            con2.SelectedChannel = 3;

            //con3.SelectedChannel = 3;

            // Do we want to add timestamp or channel name at the start of every message?
            con1.MessageFormat = ConsoleMessageFormats.All;
            //con2.MessageFormat = ConsoleMessageFormats.All;
            // Handler for altering incoming message
            //  con1.MessageSent += new ConsoleMessageEventHandler(con1_MessageSent);

            // We send initial welcome message to System channel
            con1.MessageBuffer.Add(new ConsoleMessage("System", "WELCOME TO THE SERVER! " + texto, 2));


            NeoManager.Add(tbc);
        }
        ////////////////////////////////////////////////////////////////////////////

        ////////////////////////////////////////////////////////////////////////////
        void con1_MessageSent(object sender, ConsoleMessageEventArgs e)
        {
            if (e.Message.Channel == 0)
            {
                //e.Message.Text = "(!) " + e.Message.Text;
            }//if(e.Message.Sender
        }
        ////////////////////////////////////////////////////////////////////////////

       

    
    }
}

Hello

Advertisement

In your content pipeline project, you need to set your terrain image to use the "TerrainProcessor" from the sample, instead of the regular texture processor.

i put like the example with exception this code i post

i don´t understan why don´t work

HeightMapInfoContent class


using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework.Content.Pipeline;
using Microsoft.Xna.Framework.Content.Pipeline.Graphics;
using Microsoft.Xna.Framework.Content.Pipeline.Serialization.Compiler;
using Microsoft.Xna.Framework;

namespace HeightmapCollisionPipeline
{
    /// <summary>
    /// HeightMapInfoContent contains information about a size and heights of a
    /// heightmap. When the game is being built, it is constructed by the
    /// TerrainProcessor, and attached to the finished terrain's Tag. When the game is
    /// run, it will be read in as a HeightMapInfo.
    /// </summary>
    public class HeightMapInfoContent
    {
        /// <summary>
        /// This propery is a 2D array of floats, and tells us the height that each
        /// position in the heightmap is.
        /// </summary>
        public float[,] Height
        {
            get { return height; }
        }
        float[,] height;

        /// <summary>
        /// TerrainScale is the distance between each entry in the Height property.
        /// For example, if TerrainScale is 30, Height[0,0] and Height[1,0] are 30
        /// units apart.
        /// </summary>
        public float TerrainScale
        {
            get { return terrainScale; }
        }
        private float terrainScale;

        /// <summary>
        /// This constructor will initialize the height array from the values in the 
        /// bitmap. Each pixel in the bitmap corresponds to one entry in the height
        /// array.
        /// </summary>
        public HeightMapInfoContent(PixelBitmapContent<float> bitmap,
            float terrainScale, float terrainBumpiness)
        {
            this.terrainScale = terrainScale;

            height = new float[bitmap.Width, bitmap.Height];
            for (int y = 0; y < bitmap.Height; y++)
            {
                for (int x = 0; x < bitmap.Width; x++)
                {
                    // the pixels will vary from 0 (black) to 1 (white).
                    // by subtracting 1, our heights vary from -1 to 0, which we then
                    // multiply by the "bumpiness" to get our final height.
                    height[x, y] = (bitmap.GetPixel(x, y) - 1) * terrainBumpiness;
                }
            }
        }
    }


    /// <summary>
    /// A TypeWriter for HeightMapInfo, which tells the content pipeline how to save the
    /// data in HeightMapInfo. This class should match HeightMapInfoReader: whatever the
    /// writer writes, the reader should read.
    /// </summary>
    [ContentTypeWriter]
    public class HeightMapInfoWriter : ContentTypeWriter<HeightMapInfoContent>
    {
        protected override void Write(ContentWriter output, HeightMapInfoContent value)
        {
            output.Write(value.TerrainScale);

            output.Write(value.Height.GetLength(0));
            output.Write(value.Height.GetLength(1));
            foreach (float height in value.Height)
            {
                output.Write(height);
            }
        }

        /// <summary>
        /// Tells the content pipeline what CLR type the
        /// data will be loaded into at runtime.
        /// </summary>
        public override string GetRuntimeType(TargetPlatform targetPlatform)
        {
            return "TomShane.Neoforce.Central.Code.HeightMapInfo, " +
                "TomShane.Neoforce.Central.Code, Version=1.0.0.0, Culture=neutral";
        }


        /// <summary>
        /// Tells the content pipeline what worker type
        /// will be used to load the data.
        /// </summary>
        public override string GetRuntimeReader(TargetPlatform targetPlatform)
        {
            return "TomShane.Neoforce.Central.Code.HeightMapInfoReader, " +
                "TomShane.Neoforce.Central.Code=1.0.0.0, Culture=neutral";
        }
    }
}

terrain class


using System.ComponentModel;
using System.IO;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content.Pipeline;
using Microsoft.Xna.Framework.Content.Pipeline.Graphics;
using Microsoft.Xna.Framework.Content.Pipeline.Processors;


namespace HeightmapCollisionPipeline
{
    /// <summary>
    /// Custom content processor for creating terrain meshes. Given an
    /// input heightfield texture, this processor uses the MeshBuilder
    /// class to programatically generate terrain geometry.
    /// </summary>
    [ContentProcessor]
    public class TerrainProcessor : ContentProcessor<Texture2DContent, ModelContent>
    {
        #region Properties


        private float terrainScale = 30f;
        [DisplayName("Terrain Scale")]
        [DefaultValue(30f)]
        [Description("Scale of the the terrain geometry width and length.")]
        public float TerrainScale
        {
            get { return terrainScale; }
            set { terrainScale = value; }
        }

        private float terrainBumpiness = 640f;
        [DisplayName("Terrain Bumpiness")]
        [DefaultValue(640f)]
        [Description("Scale of the the terrain geometry height.")]
        public float TerrainBumpiness
        {
            get { return terrainBumpiness; }
            set { terrainBumpiness = value; }
        }

        private float texCoordScale = 0.1f;
        [DisplayName("Texture Coordinate Scale")]
        [DefaultValue(0.1f)]
        [Description("Terrain texture tiling density.")]
        public float TexCoordScale
        {
            get { return texCoordScale; }
            set { texCoordScale = value; }
        }

        private string terrainTextureFilename = "rocks.bmp";
        [DisplayName("Terrain Texture")]
        [DefaultValue("rocks.bmp")]
        [Description("The name of the terrain texture.")]
        public string TerrainTextureFilename
        {
            get { return terrainTextureFilename; }
            set { terrainTextureFilename = value; }
        }


        #endregion

        /// <summary>
        /// Generates a terrain mesh from an input heightfield texture.
        /// </summary>
        public override ModelContent Process(Texture2DContent input,
                                             ContentProcessorContext context)
        {
            MeshBuilder builder = MeshBuilder.StartMesh("terrain");

            // Convert the input texture to float format, for ease of processing.
            input.ConvertBitmapType(typeof(PixelBitmapContent<float>));

            PixelBitmapContent<float> heightfield;
            heightfield = (PixelBitmapContent<float>)input.Mipmaps[0];

            // Create the terrain vertices.
            for (int y = 0; y < heightfield.Height; y++)
            {
                for (int x = 0; x < heightfield.Width; x++)
                {
                    Vector3 position;

                    // position the vertices so that the heightfield is centered
                    // around x=0,z=0
                    position.X = terrainScale * (x - ((heightfield.Width - 1) / 2.0f));
                    position.Z = terrainScale * (y - ((heightfield.Height - 1) / 2.0f));

                    position.Y = (heightfield.GetPixel(x, y) - 1) * terrainBumpiness;

                    builder.CreatePosition(position);
                }
            }

            // Create a material, and point it at our terrain texture.
            BasicMaterialContent material = new BasicMaterialContent();
            material.SpecularColor = new Vector3(.4f, .4f, .4f);

            string directory = Path.GetDirectoryName(input.Identity.SourceFilename);
            string texture = Path.Combine(directory, terrainTextureFilename);

            material.Texture = new ExternalReference<TextureContent>(texture);

            builder.SetMaterial(material);

            // Create a vertex channel for holding texture coordinates.
            int texCoordId = builder.CreateVertexChannel<Vector2>(
                                            VertexChannelNames.TextureCoordinate(0));

            // Create the individual triangles that make up our terrain.
            for (int y = 0; y < heightfield.Height - 1; y++)
            {
                for (int x = 0; x < heightfield.Width - 1; x++)
                {
                    AddVertex(builder, texCoordId, heightfield.Width, x, y);
                    AddVertex(builder, texCoordId, heightfield.Width, x + 1, y);
                    AddVertex(builder, texCoordId, heightfield.Width, x + 1, y + 1);

                    AddVertex(builder, texCoordId, heightfield.Width, x, y);
                    AddVertex(builder, texCoordId, heightfield.Width, x + 1, y + 1);
                    AddVertex(builder, texCoordId, heightfield.Width, x, y + 1);
                }
            }

            // Chain to the ModelProcessor so it can convert the mesh we just generated.
            MeshContent terrainMesh = builder.FinishMesh();

            ModelContent model = context.Convert<MeshContent, ModelContent>(terrainMesh,
                                                              "ModelProcessor");

            // generate information about the height map, and attach it to the finished
            // model's tag.
            model.Tag = new HeightMapInfoContent(heightfield, terrainScale,
                terrainBumpiness);

            return model;
        }


        /// <summary>
        /// Helper for adding a new triangle vertex to a MeshBuilder,
        /// along with an associated texture coordinate value.
        /// </summary>
        void AddVertex(MeshBuilder builder, int texCoordId, int w, int x, int y)
        {
            builder.SetVertexChannelData(texCoordId, new Vector2(x, y) * texCoordScale);

            builder.AddTriangleVertex(x + y * w);
        }
    }
}

//HeightMapInfo class
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework;
namespace TomShane.Neoforce.Central.Code
{
    public class HeightMapInfo
    {
        #region Private fields


        // TerrainScale is the distance between each entry in the Height property.
        // For example, if TerrainScale is 30, Height[0,0] and Height[1,0] are 30
        // units apart.        
        private float terrainScale;

        // This 2D array of floats tells us the height that each position in the 
        // heightmap is.
        private float[,] heights;

        // the position of the heightmap's -x, -z corner, in worldspace.
        private Vector3 heightmapPosition;

        // the total width of the heightmap, including terrainscale.
        private float heightmapWidth;

        // the total height of the height map, including terrainscale.
        private float heightmapHeight;


        #endregion


        // the constructor will initialize all of the member variables.
        public HeightMapInfo(float[,] heights, float terrainScale)
        {
            if (heights == null)
            {
                throw new ArgumentNullException("heights");
            }

            this.terrainScale = terrainScale;
            this.heights = heights;

            heightmapWidth = (heights.GetLength(0) - 1) * terrainScale;
            heightmapHeight = (heights.GetLength(1) - 1) * terrainScale;

            heightmapPosition.X = -(heights.GetLength(0) - 1) / 2 * terrainScale;
            heightmapPosition.Z = -(heights.GetLength(1) - 1) / 2 * terrainScale;
        }


        // This function takes in a position, and tells whether or not the position is 
        // on the heightmap.
        public bool IsOnHeightmap(Vector3 position)
        {
            // first we'll figure out where on the heightmap "position" is...
            Vector3 positionOnHeightmap = position - heightmapPosition;

            // ... and then check to see if that value goes outside the bounds of the
            // heightmap.
            return (positionOnHeightmap.X > 0 &&
                positionOnHeightmap.X < heightmapWidth &&
                positionOnHeightmap.Z > 0 &&
                positionOnHeightmap.Z < heightmapHeight);
        }

        // This function takes in a position, and returns the heightmap's height at that
        // point. Be careful - this function will throw an IndexOutOfRangeException if
        // position isn't on the heightmap!
        // This function is explained in more detail in the accompanying doc.
        public float GetHeight(Vector3 position)
        {
            // the first thing we need to do is figure out where on the heightmap
            // "position" is. This'll make the math much simpler later.
            Vector3 positionOnHeightmap = position - heightmapPosition;

            // we'll use integer division to figure out where in the "heights" array
            // positionOnHeightmap is. Remember that integer division always rounds
            // down, so that the result of these divisions is the indices of the "upper
            // left" of the 4 corners of that cell.
            int left, top;
            left = (int)positionOnHeightmap.X / (int)terrainScale;
            top = (int)positionOnHeightmap.Z / (int)terrainScale;

            // next, we'll use modulus to find out how far away we are from the upper
            // left corner of the cell. Mod will give us a value from 0 to terrainScale,
            // which we then divide by terrainScale to normalize 0 to 1.
            float xNormalized = (positionOnHeightmap.X % terrainScale) / terrainScale;
            float zNormalized = (positionOnHeightmap.Z % terrainScale) / terrainScale;

            // Now that we've calculated the indices of the corners of our cell, and
            // where we are in that cell, we'll use bilinear interpolation to calculuate
            // our height. This process is best explained with a diagram, so please see
            // the accompanying doc for more information.
            // First, calculate the heights on the bottom and top edge of our cell by
            // interpolating from the left and right sides.
            float topHeight = MathHelper.Lerp(
                heights[left, top],
                heights[left + 1, top],
                xNormalized);

            float bottomHeight = MathHelper.Lerp(
                heights[left, top + 1],
                heights[left + 1, top + 1],
                xNormalized);

            // next, interpolate between those two values to calculate the height at our
            // position.
            return MathHelper.Lerp(topHeight, bottomHeight, zNormalized);
        }
    }



    /// <summary>
    /// This class will load the HeightMapInfo when the game starts. This class needs 
    /// to match the HeightMapInfoWriter.
    /// </summary>
    public class HeightMapInfoReader : ContentTypeReader<HeightMapInfo>
    {
        protected override HeightMapInfo Read(ContentReader input,
            HeightMapInfo existingInstance)
        {
            float terrainScale = input.ReadSingle();
            int width = input.ReadInt32();
            int height = input.ReadInt32();
            float[,] heights = new float[width, height];

            for (int x = 0; x < width; x++)
            {
                for (int z = 0; z < height; z++)
                {
                    heights[x, z] = input.ReadSingle();
                }
            }
            return new HeightMapInfo(heights, terrainScale);
        }
    }
}


Hello

What does your project structure layout look like? Which projects/libraries have you created? Is the HeightmapCollisionPipeline stuff in its own project, and does your content project include a reference to that project?


i put like the example with exception this code i post

I don't understand what you mean. If there is an exception, you need to post what the exception says.

i find the soluction i only change the propritis of terrain to terrain processor

and the graphics is very poor

like you see in this pintscreen

658622bd7789960277631b902ab33439.png

Hello


and the graphics is very poor

What does that mean? What is it supposed to look like? What have you tried to do to debug it?

like the example i put in first post

Hello

it supposed to look like this

and i find the what is causing the problem but i don´t know how i fix the problem


  public override void Draw(GameTime gameTime)
        {
            //  StateManager.BeginDraw(gameTime);
            NeoManager.BeginDraw(gameTime);// the problem is this line

            GraphicsDevice.Clear(Color.CornflowerBlue);

            NeoManager.EndDraw();//and this line
            DrawModel(terrain, Matrix.Identity);

            DrawModel(sphere, sphereRollingMatrix *
                Matrix.CreateTranslation(spherePosition));
            //   ControlManager.Draw(GameRef.spriteBatch);
            base.Draw(gameTime);


        }

Hello

i find the soluction problem as been solve

i only have to reset the graphicsdevice

Hello

This topic is closed to new replies.

Advertisement