private static void drawHeightfield(HeightFieldShape heightFieldShape, GraphicsDevice device)
        {
            VertexPositionNormalTexture[] cubeVertices;
            VertexDeclaration             basicEffectVertexDeclaration;
            VertexBuffer vertexBuffer;
            var          white     = new Color(1, 1, 1, 1);
            int          vertexNum = (heightFieldShape.HeightField.NumberOfRows - 1) *
                                     (heightFieldShape.HeightField.NumberOfColumns - 1) * 3 * 2;
            var     vertices = new VertexPositionColor[vertexNum];
            int     triangleIndex;
            Vector3 pos;
            int     vertexIndex = 0;

            HeightFieldShape.GetTriangleResult triangle;
            Camera _camera = CamerasManager.Instance.GetActiveCamera();

            for (int row = 0; row < heightFieldShape.HeightField.NumberOfRows - 1; row++)
            {
                for (int column = 0; column < heightFieldShape.HeightField.NumberOfColumns - 1; column++)
                {
                    triangleIndex = 2 * (row * heightFieldShape.HeightField.NumberOfColumns + column);

                    triangle = heightFieldShape.GetTriangle(triangleIndex);


                    pos = new Vector3(triangle.WorldTriangle.Vertex2.X, triangle.WorldTriangle.Vertex2.Y,
                                      triangle.WorldTriangle.Vertex2.Z);
                    vertices[vertexIndex++] = new VertexPositionColor(pos, white);

                    pos = new Vector3(triangle.WorldTriangle.Vertex1.X, triangle.WorldTriangle.Vertex1.Y,
                                      triangle.WorldTriangle.Vertex1.Z);
                    vertices[vertexIndex++] = new VertexPositionColor(pos, white);

                    pos = new Vector3(triangle.WorldTriangle.Vertex0.X, triangle.WorldTriangle.Vertex0.Y,
                                      triangle.WorldTriangle.Vertex0.Z);
                    vertices[vertexIndex++] = new VertexPositionColor(pos, white);

                    triangleIndex++;

                    triangle = heightFieldShape.GetTriangle(triangleIndex);

                    pos = new Vector3(triangle.WorldTriangle.Vertex2.X, triangle.WorldTriangle.Vertex2.Y,
                                      triangle.WorldTriangle.Vertex2.Z);
                    vertices[vertexIndex++] = new VertexPositionColor(pos, white);

                    pos = new Vector3(triangle.WorldTriangle.Vertex1.X, triangle.WorldTriangle.Vertex1.Y,
                                      triangle.WorldTriangle.Vertex1.Z);
                    vertices[vertexIndex++] = new VertexPositionColor(pos, white);

                    pos = new Vector3(triangle.WorldTriangle.Vertex0.X, triangle.WorldTriangle.Vertex0.Y,
                                      triangle.WorldTriangle.Vertex0.Z);
                    vertices[vertexIndex++] = new VertexPositionColor(pos, white);
                }
            }
            //inicio do código do cubo
            //InitializeCube();

            basicEffectVertexDeclaration = new VertexDeclaration(
                device, VertexPositionNormalTexture.VertexElements);

            var basicEffect = new BasicEffect(device, null);

            basicEffect.Alpha             = 1.0f;
            basicEffect.DiffuseColor      = new Vector3(0.2f, 0.0f, 1.0f);
            basicEffect.SpecularColor     = new Vector3(0.25f, 0.25f, 0.25f);
            basicEffect.SpecularPower     = 5.0f;
            basicEffect.AmbientLightColor = new Vector3(0.75f, 0.75f, 0.75f);

            //basicEffect.DirectionalLight0.Enabled = true;
            //basicEffect.DirectionalLight0.DiffuseColor = Vector3.One;
            //basicEffect.DirectionalLight0.Direction = Vector3.Normalize(new Vector3(1.0f, -1.0f, -1.0f));
            //basicEffect.DirectionalLight0.SpecularColor = Vector3.One;

            //basicEffect.DirectionalLight1.Enabled = true;
            //basicEffect.DirectionalLight1.DiffuseColor = new Vector3(0.5f, 0.5f, 0.5f);
            //basicEffect.DirectionalLight1.Direction = Vector3.Normalize(new Vector3(-1.0f, -1.0f, 1.0f));
            //basicEffect.DirectionalLight1.SpecularColor = new Vector3(0.5f, 0.5f, 0.5f);

            //basicEffect.LightingEnabled = true;

            basicEffect.World      = Matrix.CreateScale(1, 1, 1);
            basicEffect.View       = _camera.View;
            basicEffect.Projection = _camera.Projection;

            //NoNameEngine.Instance.Device.Clear(Color.SteelBlue);
            //NoNameEngine.Instance.Device.RenderState.CullMode = CullMode.CullClockwiseFace;

            device.VertexDeclaration = basicEffectVertexDeclaration;

            vertexBuffer = new VertexBuffer(
                device,
                VertexPositionColor.SizeInBytes * vertexNum,
                BufferUsage.None
                );

            vertexBuffer.SetData(vertices);

            device.Vertices[0].SetSource(vertexBuffer, 0, VertexPositionColor.SizeInBytes);


            // This code would go between a NoNameEngine.Instance.Device
            // BeginScene-EndScene block.
            basicEffect.Begin();
            foreach (EffectPass pass in basicEffect.CurrentTechnique.Passes)
            {
                pass.Begin();

                //this.NoNameEngine.Instance.Device.DrawUserPrimitives<VertexPositionColor>(PrimitiveType.TriangleList, vertices, 0, vertexNum / 3);

                device.DrawPrimitives(
                    PrimitiveType.TriangleList,
                    0,
                    vertexNum / 3
                    );

                //NoNameEngine.Instance.Device.DrawPrimitives(
                //     PrimitiveType.TriangleList,
                //     0,
                //     12
                // );


                pass.End();
            }
            basicEffect.End();
        }
Exemple #2
0
        private void CreateDecalForStaticObject(ShapeTriangleID startTriangle, Vec3 pos, Vec3 normal,
                                                MapObject parentMapObject)
        {
            bool existsNormalsMore45Degrees = false;

            //find near triangles
            //Set<ShapeTriangleID> triangleIDs = new Set<ShapeTriangleID>();
            {
                Sphere checkSphere = new Sphere(pos, Type.Size * .5f * 1.41f);//Sqrt(2)

                //Set<ShapeTriangleID> checkedTriangles = new Set<ShapeTriangleID>();

                //Stack<ShapeTriangleID> trianglesForCheck = new Stack<ShapeTriangleID>( 16 );
                trianglesForCheck.Push(startTriangle);

                while (trianglesForCheck.Count != 0)
                {
                    ShapeTriangleID triangle = trianglesForCheck.Pop();

                    //add to checked triangles
                    if (!checkedTriangles.AddWithCheckAlreadyContained(triangle))
                    {
                        //ignore already checked triangles
                        continue;
                    }

                    //get triangle points
                    Vec3 p0, p1, p2;
                    {
                        switch (triangle.shape.ShapeType)
                        {
                        case Shape.Type.Mesh:
                            MeshShape meshShape = (MeshShape)triangle.shape;
                            meshShape.GetTriangle(triangle.triangleID, true, out p0, out p1, out p2);
                            break;

                        case Shape.Type.HeightField:
                            HeightFieldShape heightFieldShape = (HeightFieldShape)triangle.shape;
                            heightFieldShape.GetTriangle(triangle.triangleID, true, out p0, out p1, out p2);
                            break;

                        default:
                            Log.Fatal("DecalCreator: CreateDecalForStaticObject: Not supported shape type ({0}).",
                                      triangle.shape.ShapeType);
                            return;
                        }
                    }

                    //cull by checkBounds
                    if (!checkSphere.TriangleIntersection(p0, p1, p2))
                    {
                        continue;
                    }

                    //check normal
                    bool correctNormal = false;

                    if (Type.SpreadType != DecalCreatorType.SpreadTypes.Directional)
                    {
                        Plane plane = Plane.FromPoints(p0, p1, p2);
                        if (plane.GetSide(pos + normal) == Plane.Side.Positive)
                        {
                            Radian angle = MathFunctions.ACos(Vec3.Dot(normal, plane.Normal));

                            if (angle <= new Degree(70.0f).InRadians())
                            {
                                if (!existsNormalsMore45Degrees && angle >= new Degree(45.0f).InRadians())
                                {
                                    existsNormalsMore45Degrees = true;
                                }

                                correctNormal = true;
                            }
                        }
                    }
                    else
                    {
                        correctNormal = true;
                    }

                    if (correctNormal)
                    {
                        //add triangle to result list
                        triangleIDs.Add(triangle);
                    }

                    //add near triangles to check list
                    {
                        //expand vertices
                        const float border = .001f;
                        Vec3        center = (p0 + p1 + p2) * (1.0f / 3.0f);

                        Vec3 diff0 = p0 - center;
                        Vec3 diff1 = p1 - center;
                        Vec3 diff2 = p2 - center;

                        if (diff0 != Vec3.Zero && diff1 != Vec3.Zero && diff2 != Vec3.Zero)
                        {
                            p0 += diff0.GetNormalize() * border;
                            p1 += diff1.GetNormalize() * border;
                            p2 += diff2.GetNormalize() * border;

                            Vec3 p01 = (p0 + p1) * .5f;
                            Vec3 p12 = (p1 + p2) * .5f;
                            Vec3 p20 = (p2 + p0) * .5f;

                            //find triangles
                            for (int n = 0; n < 3; n++)
                            {
                                Vec3 p = Vec3.Zero;
                                switch (n)
                                {
                                case 0: p = p01; break;

                                case 1: p = p12; break;

                                case 2: p = p20; break;
                                }

                                RayCastResult[] piercingResult =
                                    PhysicsWorld.Instance.RayCastPiercing(new Ray(
                                                                              p + normal * .025f, -normal * .05f), (int)ContactGroup.CastOnlyCollision);
                                foreach (RayCastResult result in piercingResult)
                                {
                                    if (result.Shape != null)
                                    {
                                        trianglesForCheck.Push(new ShapeTriangleID(
                                                                   result.Shape, result.TriangleID));
                                    }
                                }
                            }
                        }
                    }
                }

                checkedTriangles.Clear();
            }

            if (triangleIDs.Count == 0)
            {
                return;
            }

            //calculate perpendiculars to normal
            Vec3 side1Normal;
            Vec3 side2Normal;

            {
                if (Math.Abs(normal.X) > .001f || Math.Abs(normal.Y) > .001f)
                {
                    side1Normal = Mat3.FromRotateByZ(MathFunctions.PI / 2) *
                                  new Vec3(normal.X, normal.Y, 0);
                    side1Normal.Normalize();
                }
                else
                {
                    side1Normal = new Vec3(1, 0, 0);
                }

                side2Normal = Vec3.Cross(normal, side1Normal);
            }

            //generate clip planes
            Plane[] clipPlanes = new Plane[6];
            {
                float halfSize = Type.Size * .5f;

                if (existsNormalsMore45Degrees)
                {
                    halfSize *= 1.41f;
                }

                Plane p;
                p             = Plane.FromVectors(normal, -side2Normal, Position);
                clipPlanes[0] = new Plane(p.Normal, p.Distance + halfSize);
                p             = Plane.FromVectors(normal, side2Normal, Position);
                clipPlanes[1] = new Plane(p.Normal, p.Distance + halfSize);
                p             = Plane.FromVectors(normal, -side1Normal, Position);
                clipPlanes[2] = new Plane(p.Normal, p.Distance + halfSize);
                p             = Plane.FromVectors(normal, side1Normal, Position);
                clipPlanes[3] = new Plane(p.Normal, p.Distance + halfSize);
                p             = Plane.FromVectors(side1Normal, side2Normal, Position);
                clipPlanes[4] = new Plane(p.Normal, p.Distance + halfSize);
                //clipPlanes[ 4 ] = new Plane( p.Normal, p.Distance + halfSize * .5f );
                p             = Plane.FromVectors(side1Normal, -side2Normal, Position);
                clipPlanes[5] = new Plane(p.Normal, p.Distance + halfSize);
                //clipPlanes[ 5 ] = new Plane( p.Normal, p.Distance + halfSize * .5f );
            }

            //generate vertices and indices by triangles
            //List<Decal.Vertex> vertices = new List<Decal.Vertex>( triangleIDs.Count * 3 );
            //List<int> indices = new List<int>( triangleIDs.Count * 3 );
            List <Decal.Vertex> vertices = tempVertices;
            List <int>          indices  = tempIndices;

            vertices.Clear();
            indices.Clear();
            {
                foreach (ShapeTriangleID triangle in triangleIDs)
                {
                    Vec3 p0, p1, p2;
                    {
                        switch (triangle.shape.ShapeType)
                        {
                        case Shape.Type.Mesh:
                            MeshShape meshShape = (MeshShape)triangle.shape;
                            meshShape.GetTriangle(triangle.triangleID, true, out p0, out p1, out p2);
                            break;

                        case Shape.Type.HeightField:
                            HeightFieldShape heightFieldShape = (HeightFieldShape)triangle.shape;
                            heightFieldShape.GetTriangle(triangle.triangleID, true, out p0, out p1, out p2);
                            break;

                        default:
                            Log.Fatal("DecalCreator: CreateDecalForStaticObject: Not supported shape type ({0}).",
                                      triangle.shape.ShapeType);
                            return;
                        }
                    }

                    List <Vec3> list = new List <Vec3>();
                    list.Add(p0);
                    list.Add(p1);
                    list.Add(p2);

                    //clip by planes
                    foreach (Plane plane in clipPlanes)
                    {
                        list = CutConvexPlanePolygonByPlane(list, plane);
                        if (list == null)
                        {
                            break;
                        }
                    }

                    //add to vertices and indices lists
                    if (list != null)
                    {
                        int vertexCount = vertices.Count;

                        Vec3 norm = Plane.FromPoints(p0, p1, p2).Normal;
                        foreach (Vec3 p in list)
                        {
                            vertices.Add(new Decal.Vertex(p, norm, Vec2.Zero, Vec3.Zero));
                        }

                        for (int n = 1; n < list.Count - 1; n++)
                        {
                            indices.Add(vertexCount);
                            indices.Add(vertexCount + n);
                            indices.Add(vertexCount + n + 1);
                        }
                    }
                }
            }

            triangleIDs.Clear();

            if (indices.Count == 0)
            {
                return;
            }

            //calculate texCoord and Type.DepthRenderOffset
            {
                Plane planeSide1 = Plane.FromVectors(normal, side1Normal, Position);
                Plane planeSide2 = Plane.FromVectors(normal, side2Normal, Position);
                float invSize    = 1.0f / Type.Size;

                for (int n = 0; n < vertices.Count; n++)
                {
                    Decal.Vertex vertex = vertices[n];

                    //calculate texCoord
                    float distance1 = planeSide1.GetDistance(vertex.position);
                    float distance2 = planeSide2.GetDistance(vertex.position);
                    vertex.texCoord = new Vec2(distance1 * invSize + .5f, distance2 * invSize + .5f);

                    //Add perpendicular to normal offset.
                    //Alternative way: for shader based rendering use DepthOffset property of decal material.
                    //if( !RenderSystem.Instance.HasShaderModel3() )
                    {
                        //add Type.DepthRenderOffset
                        vertex.position = vertex.position + normal * Type.DepthRenderOffset;
                    }

                    vertices[n] = vertex;
                }
            }

            //calculate tangent vectors
            {
                int triangleCount = indices.Count / 3;
                for (int nTriangle = 0; nTriangle < triangleCount; nTriangle++)
                {
                    int index0 = indices[nTriangle * 3 + 0];
                    int index1 = indices[nTriangle * 3 + 1];
                    int index2 = indices[nTriangle * 3 + 2];

                    Decal.Vertex vertex0 = vertices[index0];
                    Decal.Vertex vertex1 = vertices[index1];
                    Decal.Vertex vertex2 = vertices[index2];

                    Vec3 tangent = MathUtils.CalculateTangentSpaceVector(
                        vertex0.position, vertex0.texCoord,
                        vertex1.position, vertex1.texCoord,
                        vertex2.position, vertex2.texCoord);

                    vertex0.tangent += tangent;
                    vertex1.tangent += tangent;
                    vertex2.tangent += tangent;

                    vertices[index0] = vertex0;
                    vertices[index1] = vertex1;
                    vertices[index2] = vertex2;
                }

                for (int n = 0; n < vertices.Count; n++)
                {
                    Decal.Vertex vertex = vertices[n];
                    if (vertex.tangent != Vec3.Zero)
                    {
                        vertex.tangent.Normalize();
                    }
                    vertices[n] = vertex;
                }
            }

            //subtract decal position (make local vertices coordinates)
            {
                for (int n = 0; n < vertices.Count; n++)
                {
                    Decal.Vertex vertex = vertices[n];
                    vertex.position -= Position;
                    vertices[n]      = vertex;
                }
            }

            //get material
            string materialName = null;
            {
                string physicsMaterialName = startTriangle.shape.MaterialName;
                string defaultMaterialName = "";

                foreach (DecalCreatorType.MaterialItem item in Type.Materials)
                {
                    if (item.PhysicsMaterialName == physicsMaterialName)
                    {
                        materialName = item.MaterialName;
                    }

                    if (string.IsNullOrEmpty(item.PhysicsMaterialName))
                    {
                        defaultMaterialName = item.MaterialName;
                    }
                }

                if (materialName == null)
                {
                    materialName = defaultMaterialName;
                }
            }

            //create Decal
            Decal decal = (Decal)Entities.Instance.Create("Decal", Map.Instance);

            decal.Position = Position;
            decal.Init(this, vertices.ToArray(), indices.ToArray(), materialName, parentMapObject);
            decal.PostCreate();
            Type.AddDecalToCreatedList(decal);
            decals.Add(decal);
        }