Exemplo n.º 1
0
        protected override void OnEnabledInHierarchyChanged()
        {
            base.OnEnabledInHierarchyChanged();

            if (EnabledInHierarchy)
            {
                //get free camera initial settings
                if (EngineApp.ApplicationType == EngineApp.ApplicationTypeEnum.Simulation)
                {
                    var scene = Parent as Component_Scene;
                    if (scene != null)
                    {
                        Component_Camera camera = scene.CameraDefault;
                        if (camera == null)
                        {
                            camera = scene.Mode.Value == Component_Scene.ModeEnum._2D ? scene.CameraEditor2D : scene.CameraEditor;
                        }

                        if (camera != null)
                        {
                            var tr = camera.TransformV;
                            freeCameraPosition  = tr.Position;
                            freeCameraDirection = SphericalDirection.FromVector(tr.Rotation.GetForward());
                        }
                    }
                }
            }
        }
Exemplo n.º 2
0
        public static void Multiply(ref SphericalDirection d, ref Quaternion q, out SphericalDirection result)
        {
            Vector3 vector;

            d.GetVector(out vector);
            Vector3 vector2;

            Quaternion.Multiply(ref vector, ref q, out vector2);
            SphericalDirection.FromVector(ref vector2, out result);
        }
Exemplo n.º 3
0
        protected override void OnEnabledInHierarchyChanged()
        {
            base.OnEnabledInHierarchyChanged();

            if (EnabledInHierarchy)
            {
                var character = Character;
                if (character != null)
                {
                    //get initial look direction
                    lookDirection = SphericalDirection.FromVector(character.TransformV.Rotation.GetForward());
                }
            }
        }
Exemplo n.º 4
0
        public static void GenerateIcoSphere(double radius, int subdivisions, bool insideOut,
                                             out Vector3[] positions, out Vector3[] normals, out Vector4[] tangents, out Vector2[] texCoords, out int[] indices, out Face[] faces)
        {
            var faceCount = 20;         // 20 faces, icosahedronIndexes.Length / 3
            var vCount    = 12;         // 12 vertices
            var divCount  = subdivisions;

            /*   /\
             *  /  \
             * /____\
             * /\    /\
             * /  \  /  \
             * /____\/____\  */

            while (divCount-- > 0)
            {
                // 3 new vetices for each face
                vCount += faceCount * 3;
                // subdivide each face by 4 new ones
                faceCount *= 4;
            }

            List <int> vertexIndexList;            //viList.count == pList.Count (the vertex index of element in pList)
            var        pList     = new List <Vector3>(vCount);
            var        nList     = new List <Vector3>(vCount);
            var        tList     = new List <Vector4>(vCount);
            var        txList    = new List <Vector2>(vCount);
            var        indexList = new List <int>(icosahedronIndexes);

            var t = (1.0 + Math.Sqrt(5.0)) / 2.0;

            //icosahedron
            nList.Add(new Vector3(-1, t, 0).GetNormalize());
            nList.Add(new Vector3(1, t, 0).GetNormalize());
            nList.Add(new Vector3(-1, -t, 0).GetNormalize());
            nList.Add(new Vector3(1, -t, 0).GetNormalize());

            nList.Add(new Vector3(0, -1, t).GetNormalize());
            nList.Add(new Vector3(0, 1, t).GetNormalize());
            nList.Add(new Vector3(0, -1, -t).GetNormalize());
            nList.Add(new Vector3(0, 1, -t).GetNormalize());

            nList.Add(new Vector3(t, 0, -1).GetNormalize());
            nList.Add(new Vector3(t, 0, 1).GetNormalize());
            nList.Add(new Vector3(-t, 0, -1).GetNormalize());
            nList.Add(new Vector3(-t, 0, 1).GetNormalize());

            foreach (var n in nList)
            {
                pList.Add(n * radius);
            }

            //!!!!GC
            var cache = new Dictionary <long, int>();

            // Refine faces
            for (int iter = 0; iter < subdivisions; iter++)
            {
                var newindices = new List <int>(indexList.Count / 3 * 12);

                for (int i = 0; i < indexList.Count / 3; i++)
                {
                    var i1 = indexList[i * 3];
                    var i2 = indexList[i * 3 + 1];
                    int i3 = indexList[i * 3 + 2];

                    // get mid points
                    int a = CreateMiddlePoint(pList, i1, i2, cache, radius, nList);
                    int b = CreateMiddlePoint(pList, i2, i3, cache, radius, nList);
                    int c = CreateMiddlePoint(pList, i3, i1, cache, radius, nList);

                    //Push 4 triangles
                    newindices.Add(i1);
                    newindices.Add(a);
                    newindices.Add(c);

                    newindices.Add(i2);
                    newindices.Add(b);
                    newindices.Add(a);

                    newindices.Add(i3);
                    newindices.Add(c);
                    newindices.Add(b);

                    newindices.Add(a);
                    newindices.Add(b);
                    newindices.Add(c);
                }

                indexList = newindices;
            }

            //tangents and texcoords
            {
                var rotationMatrix = new Matrix3(0, -1, 0, 1, 0, 0, 0, 0, 1);

                for (int n = 0; n < nList.Count; n++)
                {
                    var     p   = nList[n];
                    var     rot = Quaternion.FromDirectionZAxisUp(p).ToMatrix3() * rotationMatrix;
                    Vector4 tan;
                    if (insideOut)
                    {
                        tan = new Vector4(rot * Vector3.XAxis, -1);
                    }
                    else
                    {
                        tan = new Vector4(rot * -Vector3.XAxis, -1);
                    }

                    tList.Add(tan);

                    var dir = SphericalDirection.FromVector(p);

                    var tx = new Vector2(
                        dir.Horizontal / (MathEx.PI * 2) * 2,                     // [-1..1]
                        -dir.Vertical / MathEx.PI + 0.5);                         // [0..1]

                    //var tx = new Vec2(
                    //	( 0.5 - Math.Atan2( p.X, p.Z ) /  Math.PI * 2 ),
                    //	( 0.5 - Math.Asin( p.Y ) / Math.PI ));

                    txList.Add(tx);
                }
            }

            bool upUsed   = false;
            bool downUsed = false;

            //all the vertices in pList now have the unique positions. No more unique positions.
            vertexIndexList = new List <int>(pList.Count);
            for (int i = 0; i < pList.Count; i++)
            {
                vertexIndexList.Add(i);
            }


            // Correct poles.
            for (int i = 0; i < indexList.Count; i += 3)
            {
                var vidx1 = indexList[i];
                var vidx2 = indexList[i + 1];
                var vidx3 = indexList[i + 2];

                var n1 = nList[vidx1];
                var n2 = nList[vidx2];
                var n3 = nList[vidx3];

                if (Math.Abs(n1.Z) == 1)
                {
                    var dirUp = SphericalDirection.FromVector(n1);
                    var mid   = (pList[vidx2] + pList[vidx3]) * .5;
                    var dir   = SphericalDirection.FromVector(Vector3.Normalize(mid));
                    dir.Vertical = dirUp.Vertical;

                    var txt = new Vector2(
                        dir.Horizontal / (MathEx.PI * 2) * 2,                     // [-1..1]
                        -dir.Vertical / MathEx.PI + 0.5);                         // [0..1]

                    var update = false;

                    if (n1.Z == 1 && !upUsed)                     //up
                    {
                        update = true;
                        upUsed = true;
                    }
                    if (n1.Z == -1 && !downUsed)                     //down
                    {
                        update   = true;
                        downUsed = true;
                    }

                    if (update)
                    {
                        txList[vidx1] = txt;
                    }
                    else
                    {
                        // vertex1 is new pole, duplicate it and update the face.
                        //newVertexIndex = pList.Count;
                        indexList[i] = pList.Count;

                        pList.Add(pList[vidx1]);
                        vertexIndexList.Add(vertexIndexList[vidx1]);
                        nList.Add(nList[vidx1]);
                        tList.Add(tList[vidx1]);
                        txList.Add(txt);
                    }
                }
                else if (Math.Abs(n2.Z) == 1)
                {
                    var dirUp = SphericalDirection.FromVector(n2);
                    var mid   = (pList[vidx1] + pList[vidx3]) * .5;
                    var dir   = SphericalDirection.FromVector(Vector3.Normalize(mid));
                    dir.Vertical = dirUp.Vertical;

                    var txt = new Vector2(
                        dir.Horizontal / (MathEx.PI * 2) * 2,                     // [-1..1]
                        -dir.Vertical / MathEx.PI + 0.5);                         // [0..1]

                    var update = false;

                    if (n1.Z == 1 && !upUsed)                     //up
                    {
                        update = true;
                        upUsed = true;
                    }
                    if (n1.Z == -1 && !downUsed)                     //down
                    {
                        update   = true;
                        downUsed = true;
                    }

                    if (update)
                    {
                        txList[vidx2] = txt;
                    }
                    else
                    {
                        // vertex2 is new pole, duplicate it and update the face.
                        //newVertexIndex = pList.Count;
                        indexList[i + 1] = pList.Count;

                        pList.Add(pList[vidx2]);
                        vertexIndexList.Add(vertexIndexList[vidx2]);
                        nList.Add(nList[vidx2]);
                        tList.Add(tList[vidx2]);
                        txList.Add(txt);
                    }
                }
                else if (Math.Abs(n3.Z) == 1)
                {
                    var dirUp = SphericalDirection.FromVector(n3);
                    var mid   = (pList[vidx1] + pList[vidx2]) * .5;
                    var dir   = SphericalDirection.FromVector(Vector3.Normalize(mid));
                    dir.Vertical = dirUp.Vertical;

                    var txt = new Vector2(
                        dir.Horizontal / (MathEx.PI * 2) * 2,                     // [-1..1]
                        -dir.Vertical / MathEx.PI + 0.5);                         // [0..1]

                    var update = false;

                    if (n1.Z == 1 && !upUsed)                     //up
                    {
                        update = true;
                        upUsed = true;
                    }
                    if (n1.Z == -1 && !downUsed)                     //down
                    {
                        update   = true;
                        downUsed = true;
                    }

                    if (update)
                    {
                        txList[vidx3] = txt;
                    }
                    else
                    {
                        // vertex3 is new pole, duplicate it and update the face.
                        //newVertexIndex = pList.Count;
                        indexList[i + 2] = pList.Count;

                        pList.Add(pList[vidx3]);
                        vertexIndexList.Add(vertexIndexList[vidx3]);
                        nList.Add(nList[vidx3]);
                        tList.Add(tList[vidx3]);
                        txList.Add(txt);
                    }
                }
            }

            //!!!!GC
            var correctionMap = new Dictionary <int, int>();

            //correct seam
            for (int i = indexList.Count - 3; i >= 0; i -= 3)
            {
                var v0 = new Vector3(txList[indexList[i + 0]], 0);
                var v1 = new Vector3(txList[indexList[i + 1]], 0);
                var v2 = new Vector3(txList[indexList[i + 2]], 0);

                var cross = Vector3.Cross(v0 - v1, v2 - v1);

                if (cross.Z <= 0)                 //test if the face crosses a texture boundary.
                {
                    for (var j = i; j < i + 3; j++)
                    {
                        var index    = indexList[j];
                        var texCoord = txList[index];
                        var shift    = 0.0;

                        if (texCoord.X >= .8)
                        {
                            shift = -2;
                        }

                        //if( texCoord.X <= -.8 )
                        //	shift = 2;

                        if (shift == 0)
                        {
                            continue;
                        }

                        if (correctionMap.ContainsKey(index))
                        {
                            indexList[j] = correctionMap[index];
                        }
                        else
                        {
                            texCoord.X += shift;

                            txList.Add(texCoord);

                            pList.Add(pList[index]);
                            vertexIndexList.Add(vertexIndexList[index]);
                            nList.Add(nList[index]);
                            tList.Add(tList[index]);

                            var correctedVertexIndex = txList.Count - 1;

                            correctionMap.Add(index, correctedVertexIndex);

                            indexList[j] = correctedVertexIndex;
                        }
                    }
                }
            }

            positions = pList.ToArray();
            normals   = nList.ToArray();
            tangents  = tList.ToArray();
            texCoords = txList.ToArray();
            indices   = indexList.ToArray();

            if (insideOut)
            {
                var idx = 0;
                while (idx < indices.Length)
                {
                    var temp = indices[idx + 1];
                    indices[idx + 1] = indices[idx + 2];
                    indices[idx + 2] = temp;
                    idx += 3;
                }

                idx = 0;
                while (idx < normals.Length)
                {
                    Vector3.Negate(ref normals[idx], out normals[idx]);
                    idx++;
                }

                for (int n = 0; n < texCoords.Length; n++)
                {
                    texCoords[n] = new Vector2(1.0f - texCoords[n].X, texCoords[n].Y);
                }
            }


            const int rawVerticesInFace = 3;

            faces = new Face[indices.Length / rawVerticesInFace];
            for (int i = 0; i < indices.Length; i += rawVerticesInFace)
            {
                faces[i / 3] = new Face(new FaceVertex[] {
                    new FaceVertex(vertexIndexList[indices[i]], indices[i]),
                    new FaceVertex(vertexIndexList[indices[i + 1]], indices[i + 1]),
                    new FaceVertex(vertexIndexList[indices[i + 2]], indices[i + 2]),
                });
            }

            //faces = new Face[ indices.Length / rawVerticesInFace ];
            //int curTriangle = 0;
            //int curFace = 0;
            //FaceVertex[] faceTriangles = null;
            //for( int i = 0; i < indices.Length; i++ )
            //{
            //	if( faceTriangles == null )
            //	{
            //		faceTriangles = new FaceVertex[ rawVerticesInFace ];
            //		curTriangle = 0;
            //	}
            //	faceTriangles[ curTriangle++ ] = new FaceVertex( vertexIndexList[ indices[ i ] ], indices[ i ] );

            //	if( curTriangle == rawVerticesInFace )
            //	{
            //		faces[ curFace++ ] = new Face( faceTriangles );
            //		faceTriangles = null;
            //	}
            //}
        }