testing on wp7 device

Discuss any questions about BEPUphysics or problems encountered.
Post Reply
RyanGadz
Posts: 32
Joined: Thu Aug 12, 2010 8:34 pm
Contact:

testing on wp7 device

Post by RyanGadz »

i tweaked the physics on my game in the emulator to the point i like it but now going to the actual device everything seems messed up, as well as painfully slow at times. im now trying to simplify the physics to make it run more sloothly but some odd things also are starting to happen... any tips i should know about?
Norbo
Site Admin
Posts: 4929
Joined: Tue Jul 04, 2006 4:45 am

Re: testing on wp7 device

Post by Norbo »

If you're seeing actual behavioral differences between the emulator and device, then you're probably encountering some shenanigans. I have heard reports of such phone shenanigans, though I have yet to narrow down the cause as I do not yet have a device.

I suggest verifying the content that's being loaded to make sure that it's actually what you expect. You might be able to use the WP7 BEPUphysicsDrawer to draw any StaticTriangleGroup's TriangleMesh to see what is really being loaded in. I have heard reports of content files possibly being loaded differently on the device versus the emulator, leading to degenerate or gigantic triangles. They will cause all sorts of problems, likely including bad performance.

If there are no behavior differences between the emulator and device, the standard performance suggestions apply: reduce Space.SimulationSettings.CollisionResponse.Iterations (at the cost of accuracy), reduce possible active entities, simplify geometry, etc. These solutions probably won't help much if the aforementioned shenanigans are present, though.
RyanGadz
Posts: 32
Joined: Thu Aug 12, 2010 8:34 pm
Contact:

Re: testing on wp7 device

Post by RyanGadz »

thanks! that gives me more things to try.

right now while shooting the ball in my golf game it will suddenly bounce when the terrain is near level. it seems to pass though the edge of the playing field and my trees (all static triangle groups). it also never falls into the hole. everything was flawless on the emulator :(

on the second hole, it loads up my graphics and just freezes halway though (something ive noticed on your car demo as well)

that said, the phone performs beautifully, running all my 3d graphics smoothly. the first thing i did was drop down to 240x400 and disabled multisampling, but it seems to handle any graphics i throw at it, so i put everything back to the way i had it.
RyanGadz
Posts: 32
Joined: Thu Aug 12, 2010 8:34 pm
Contact:

Re: testing on wp7 device

Post by RyanGadz »

what i have seen is:
once i saved the meshes from the least amount of triangles possible in Maya 2011, the game seemed to work fine and as fast as on the emulator!

not sure exactly what this means but it does allow me to work around this recent problem we all seem to be having. ill use smaller mesh triangle groups for now and overlay smoother mesh for just the graphics. might not even be able to tell most of the time...

the biggest problem with this method is the game might end up being too large for over the air downloads :(
Norbo
Site Admin
Posts: 4929
Joined: Tue Jul 04, 2006 4:45 am

Re: testing on wp7 device

Post by Norbo »

That's interesting, and shares some details with another report I've heard. In that situation, after a certain size of mesh, the errors started happening and new vertices were wrong in a whole variety of ways. It was a relatively low value of vertices- I don't remember exactly what it was, but it was substantially below the Reach profile limits.
RyanGadz
Posts: 32
Joined: Thu Aug 12, 2010 8:34 pm
Contact:

Re: testing on wp7 device

Post by RyanGadz »

so i just updated to 0.14.3 ... and its worse than before .. much much worse. my gamescreen wont even load correctly on any types of graphics and map/hole/level that was working now has the ball bounce around in space making weird movement before i even do anything.

.. did i replace the .dll correctly? what would cause this to happen?
Norbo
Site Admin
Posts: 4929
Joined: Tue Jul 04, 2006 4:45 am

Re: testing on wp7 device

Post by Norbo »

It sounds like something else is going on that's probably not related directly to BEPUphysics. The loading of a gamescreen doesn't have anything to do with the physics engine, unless you were using the BEPUphysics TriangleMesh.GetVerticesAndIndicesFromModel for something.

By the way, the suggested approach is still to use a content processor to extract vertices from a model in the general case.
RyanGadz
Posts: 32
Joined: Thu Aug 12, 2010 8:34 pm
Contact:

Re: testing on wp7 device

Post by RyanGadz »

so is this wrong?

Code: Select all

            structure = new Model[mapDecor.numS];
            dataStructure = new DataStructure[mapDecor.numS];
            for (var i = 0; i < mapDecor.numS; i++)
            {
                structure[i] = content.Load<Model>(mapDecor.structure[i]);
                int[] indices;
                StaticTriangleGroup.StaticTriangleGroupVertex[] vertices;
                StaticTriangleGroup.GetVerticesAndIndicesFromModel(structure[i], out vertices, out indices);
                var mesh = new TriangleMesh(vertices, indices);
                var group = new StaticTriangleGroup(mesh);
                space.Add(group);
                var size = Matrix.CreateScale(1, 1, 1);
                ScreenManager.Game.Components.Add(new DataStructure(group, structure[i], size, ScreenManager.Game));
                dataStructure[i] = new DataStructure(group, structure[i], size, ScreenManager.Game);
            }
Norbo
Site Admin
Posts: 4929
Joined: Tue Jul 04, 2006 4:45 am

Re: testing on wp7 device

Post by Norbo »

The actual vertex extraction part seems fine. But again, using the convenience function isn't going to cause a game screen to load badly or anything like that.
RyanGadz
Posts: 32
Joined: Thu Aug 12, 2010 8:34 pm
Contact:

Re: testing on wp7 device

Post by RyanGadz »

lol it does have trouble loading if the gravity is set before any of the graphics or entities are loaded. oops

loading is fine now...

.. but nothing is colliding... sigh
Norbo
Site Admin
Posts: 4929
Joined: Tue Jul 04, 2006 4:45 am

Re: testing on wp7 device

Post by Norbo »

If you haven't already, you might want to just switch to using a content processor based method to eliminate it as a possible issue. There's some information about setting up a processor in this thread, and of course in the xna site's resources: http://www.bepu-games.com/forums/viewto ... f=4&t=1025

The lack of collision might be something as simple as the mesh being transformed somewhere else, though.
RyanGadz
Posts: 32
Joined: Thu Aug 12, 2010 8:34 pm
Contact:

Re: testing on wp7 device

Post by RyanGadz »

thanks,

i guess i still dont know what you mean by content processor, but ill look into it.

just to check, i switched back to 0.14.2 and everything worked fine again (only on the emulator)
RyanGadz
Posts: 32
Joined: Thu Aug 12, 2010 8:34 pm
Contact:

Re: testing on wp7 device

Post by RyanGadz »

i now have a content processor and it works for most of my geomtery but some stuff is still coming in wrong. all the graphics are correct but some (not all) of my staticTriangleGroups are messed up

its always perfect on the emulator, the only problem is on the actual phone

Code: Select all

                structure[i] = content.Load<Model>(mapDecor.structure[i]);
                VertexHelper.ExtractTrianglesFrom(structure[i], vertexHelper.vertices, vertexHelper.indices, size );
                StaticTriangleGroup.StaticTriangleGroupVertex[] verts = new StaticTriangleGroup.StaticTriangleGroupVertex[vertexHelper.vertices.Count];
                int[] indexArray = new int[vertexHelper.indices.Count * 3];
                for(int v = 0; v< vertexHelper.vertices.Count; v++)
                {
                    verts [v] = new StaticTriangleGroup.StaticTriangleGroupVertex(vertexHelper.vertices[v]);
                        
                }
                int a = 0;
                int count = vertexHelper.indices.Count * 3;
                for (int p = 0; p < count; p=p+3)
                {

                    indexArray[p] = vertexHelper.indices[a].A;
                    indexArray[p+1] = vertexHelper.indices[a].B;
                    indexArray[p+2] = vertexHelper.indices[a].C;
                    a++;
                }
                

                var mesh = new TriangleMesh(verts, indexArray);
                var group = new StaticTriangleGroup(mesh);
                vertexHelper.indices.Clear();
                vertexHelper.vertices.Clear();

               
             
                space.Add(group);

Code: Select all

#region Using Statements
using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using BEPUphysics;
#endregion

namespace BonsaiGolf
{
    public class VertexHelper
    {
       public List<Vector3> vertices = new List<Vector3>();
       public List<TriangleVertexIndices> indices = new List<TriangleVertexIndices>();
        
        public VertexHelper()
        {
        }

        public struct TriangleVertexIndices
        {
            public int A;
            public int B;
            public int C;
        }

        /// <summary>
        /// Extract the vertices and indices from the specified model
        /// </summary>
        /// <param name="vertices">Output the list of vertices</param>
        /// <param name="indices">Output the list of indices</param>
        /// <param name="worldPosition">The models world position or use Matrix.Identity for object space</param>
        public static void ExtractTrianglesFrom(Model modelToUse, List<Vector3> vertices, List<TriangleVertexIndices> indices, Matrix worldPosition)
        {
            Matrix transform = Matrix.Identity;

            foreach (ModelMesh mesh in modelToUse.Meshes)
            {
                // If the model has bones the vertices have to be transformed by the bone position
                transform = Matrix.Multiply(GetAbsoluteTransform(mesh.ParentBone), worldPosition);

                ExtractModelMeshData(mesh, ref transform, vertices, indices);
            }
        }

        /// <summary>
        /// Transform by a bone position or Identity if no bone is supplied
        /// </summary>
        public static Matrix GetAbsoluteTransform(ModelBone bone)
        {
            if (bone == null)
            {
                return Matrix.Identity;
            }
            return bone.Transform * GetAbsoluteTransform(bone.Parent);
        }

        /// <summary>
        /// Get all the triangles from all mesh parts
        /// </summary>
        public static void ExtractModelMeshData(ModelMesh mesh, ref Matrix transform,
            List<Vector3> vertices, List<TriangleVertexIndices> indices)
        {
            foreach (ModelMeshPart meshPart in mesh.MeshParts)
            {
                ExtractModelMeshPartData(meshPart, ref transform, vertices, indices);
            }
        }

        /// <summary>
        /// Get all the triangles from each mesh part (Changed for XNA 4)
        /// </summary>
        public static void ExtractModelMeshPartData(ModelMeshPart meshPart, ref Matrix transform,
            List<Vector3> vertices, List<TriangleVertexIndices> indices)
        {
            // Before we add any more where are we starting from

              int  offset = vertices.Count;


            // == Vertices (Changed for XNA 4.0)

            // Read the format of the vertex buffer
            VertexDeclaration declaration = meshPart.VertexBuffer.VertexDeclaration;
            VertexElement[] vertexElements = declaration.GetVertexElements();
            // Find the element that holds the position
            VertexElement vertexPosition = new VertexElement();
            foreach (VertexElement vert in vertexElements)
            {
                if (vert.VertexElementUsage == VertexElementUsage.Position &&
                    vert.VertexElementFormat == VertexElementFormat.Vector3)
                {
                    vertexPosition = vert;
                    // There should only be one
                    break;
                }
            }
            // Check the position element found is valid
            if (vertexPosition == null ||
                vertexPosition.VertexElementUsage != VertexElementUsage.Position ||
                vertexPosition.VertexElementFormat != VertexElementFormat.Vector3)
            {
                throw new Exception("Model uses unsupported vertex format!");
            }
            // This where we store the vertices until transformed
            Vector3[] allVertex = new Vector3[meshPart.NumVertices];
            // Read the vertices from the buffer in to the array
            meshPart.VertexBuffer.GetData<Vector3>(
                meshPart.VertexOffset * declaration.VertexStride + vertexPosition.Offset,
                allVertex,
                0,
                meshPart.NumVertices,
                declaration.VertexStride);
            // Transform them based on the relative bone location and the world if provided
            for (int i = 0; i != allVertex.Length; ++i)
            {
                Vector3.Transform(ref allVertex[i], ref transform, out allVertex[i]);
            }
            // Store the transformed vertices with those from all the other meshes in this model
            vertices.AddRange(allVertex);
          
            // == Indices (Changed for XNA 4)

            // Find out which vertices make up which triangles
            if (meshPart.IndexBuffer.IndexElementSize != IndexElementSize.SixteenBits)
            {
                // This could probably be handled by using int in place of short but is unnecessary
                throw new Exception("Model uses 32-bit indices, which are not supported.");
            }
            // Each primitive is a triangle
            short[] indexElements = new short[meshPart.PrimitiveCount * 3];
            meshPart.IndexBuffer.GetData<short>(
                meshPart.StartIndex * 2,
                indexElements,
                0,
                meshPart.PrimitiveCount * 3);
            // Each TriangleVertexIndices holds the three indexes to each vertex that makes up a triangle
            TriangleVertexIndices[] tvi = new TriangleVertexIndices[meshPart.PrimitiveCount];
            for (int i = 0; i != tvi.Length; ++i)
            {
                // The offset is becuase we are storing them all in the one array and the 
                // vertices were added to the end of the array.
                tvi[i].A = indexElements[i * 3 + 0] ;
                tvi[i].B = indexElements[i * 3 + 1];
                tvi[i].C = indexElements[i * 3 + 2];

            
            }
            // Store our triangles
            indices.AddRange(tvi);
       
        }



    }
}
Norbo
Site Admin
Posts: 4929
Joined: Tue Jul 04, 2006 4:45 am

Re: testing on wp7 device

Post by Norbo »

You're running into the same bug I did with VertexBuffer.GetData. That overload cannot be used on the phone hardware, unfortunately (yet). The benefit of running a build-time content processor is that it doesn't matter what platform it ends up running on; the exact same data will be loaded in. I should have clarified earlier that the content processor referred to such a build-time processor that hooks into the XNA content pipeline.

Check the triangle picking XNA sample for an example of a build-time content processor that can help bypass the runtime problems with the VertexBuffer.GetData method.
Post Reply