예제 #1
0
        public Entity GetEntity(Chunk xiRootChunk, eTextureMode xiTextureMode, eTexMetaDataEntries xiSelectedMetadata, object xiMeshOwner)
        {
            MMEdEntity             lAcc                     = new MMEdEntity(xiMeshOwner);
            Mesh                   lColouredMesh            = null;
            Dictionary <int, Mesh> lPageIdToTexturedMeshMap = new Dictionary <int, Mesh>();
            List <Mesh>            lTranslucentMeshes       = new List <Mesh>();

            //qq move all this into Face class?
            //qq add quad mode meshes (needs separate meshes currently...)
            Vertex[] lVBuff = new Vertex[4];
            foreach (Face f in Faces)
            {
                if (!f.IsUnknownType())
                {
                    for (int v = 0; v < f.mVertexIds.Length; v++)
                    {
                        lVBuff[v] = new Vertex(ThreeDeeViewer.Short3CoordToPoint(Vertices[f.mVertexIds[v]]));

                        //normal
                        if (v < f.mNormalIds.Length)
                        {
                            lVBuff[v].Normal = ThreeDeeViewer.Short3CoordToPoint(Normals[f.mNormalIds[v]]).GetPositionVector().Normalise();
                        }
                        else
                        {
                            lVBuff[v].Normal = ThreeDeeViewer.Short3CoordToPoint(Normals[f.mNormalIds[0]]).GetPositionVector().Normalise();
                        }

                        //color:
                        if (f.mColors != null && v < f.mColors.Length)
                        {
                            lVBuff[v].Color = Utils.PSRGBColorToColor(f.mColors[v]);
                        }
                        else if (f.mColors != null)
                        {
                            lVBuff[v].Color = Utils.PSRGBColorToColor(f.mColors[0]);
                        }

                        //tex coords
                        if (f.mTexCoords != null && v < f.mTexCoords.Length)
                        {
                            lVBuff[v].TexCoordX = f.mTexCoords[v].X / (double)VRAMViewer.TEX_PAGE_WIDTH;
                            lVBuff[v].TexCoordY = f.mTexCoords[v].Y / (double)VRAMViewer.TEX_PAGE_HEIGHT;
                        }
                    }

                    // Create a new mesh if appropriate, or add this face to an existing mesh
                    // First check if it's tex or solid?
                    Mesh lMesh;
                    if (f.mTexCoords != null)
                    {
                        if (!lPageIdToTexturedMeshMap.ContainsKey(f.mTexPage))
                        {
                            lMesh = new OwnedMesh(xiMeshOwner);
                            lPageIdToTexturedMeshMap[f.mTexPage] = lMesh;

                            if (xiTextureMode == eTextureMode.NormalTextures ||
                                xiTextureMode == eTextureMode.NormalTexturesWithMetadata)
                            {
                                lMesh.RenderMode = RenderMode.Textured;
                                lMesh.Texture    = AbstractRenderer.ImageToTextureId(
                                    VRAMViewer.GetInstance().GetTexturePage(xiRootChunk, f.mTexPage));
                            }
                            else
                            {
                                lMesh.RenderMode = RenderMode.Wireframe;
                            }
                        }
                        else
                        {
                            lMesh = lPageIdToTexturedMeshMap[f.mTexPage];
                        }
                    }
                    else
                    {
                        if (f.IsTranslucent())
                        {
                            lMesh = new OwnedMesh(xiMeshOwner);
                            if (xiTextureMode == eTextureMode.NormalTextures ||
                                xiTextureMode == eTextureMode.NormalTexturesWithMetadata)
                            {
                                lMesh.RenderMode = RenderMode.TranslucentFilled;
                            }
                            else
                            {
                                lMesh.RenderMode = RenderMode.Wireframe;
                            }
                            lTranslucentMeshes.Add(lMesh);
                        }
                        else
                        {
                            if (lColouredMesh == null)
                            {
                                lColouredMesh = new OwnedMesh(xiMeshOwner);

                                if (xiTextureMode == eTextureMode.NormalTextures ||
                                    xiTextureMode == eTextureMode.NormalTexturesWithMetadata)
                                {
                                    lColouredMesh.RenderMode = RenderMode.Filled;
                                }
                                else
                                {
                                    lColouredMesh.RenderMode = RenderMode.Wireframe;
                                }
                            }
                            lMesh = lColouredMesh;
                        }
                    }

                    if (f.mVertexIds.Length == 3)
                    {
                        lMesh.AddFace(lVBuff[0], lVBuff[1], lVBuff[2]);
                    }
                    else //4
                    {
                        lMesh.AddFace(lVBuff[0], lVBuff[1], lVBuff[2]);
                        lMesh.AddFace(lVBuff[0], lVBuff[2], lVBuff[3]);
                    }
                }
            }

            foreach (Mesh lTexturedMesh in lPageIdToTexturedMeshMap.Values)
            {
                lAcc.Meshes.Add(lTexturedMesh);
            }
            if (lColouredMesh != null)
            {
                lAcc.Meshes.Add(lColouredMesh);
            }
            lAcc.Meshes.AddRange(lTranslucentMeshes);

            lAcc.Scale(1, 1, -1);

            return(lAcc);
        }
예제 #2
0
 public IEnumerable <GLTK.Entity> GetEntities(Chunk xiRootChunk, eTextureMode xiTextureMode, eTexMetaDataEntries xiSelectedMetadata)
 {
     return(SHET.GetEntities(xiRootChunk, xiTextureMode, xiSelectedMetadata));
 }
예제 #3
0
 public IEnumerable <GLTK.Entity> GetEntities(Chunk xiRootChunk, eTextureMode xiTextureMode, eTexMetaDataEntries xiSelectedMetadata)
 {
     return(new Entity[] { GetEntity(xiRootChunk, xiTextureMode, xiSelectedMetadata, this) });
 }
예제 #4
0
        public IEnumerable<GLTK.Entity> GetEntities(Level xiLevel, eTextureMode xiTextureMode, eTexMetaDataEntries xiSelectedMetadata)
        {
            List<Entity> lAcc = new List<Entity>();

              //a bit hacky:
              if (!this.TreeNode.Checked)
              {
            lAcc.Add(GetSurfaceEntity(xiLevel, xiTextureMode, xiSelectedMetadata));
              }

              /////////////////////////////////////////////////////
              // The child weapons
              if (Weapons != null)
              {
            foreach (WeaponEntry lWeapon in Weapons)
            {
              lAcc.AddRange(lWeapon.GetEntities(xiLevel, xiTextureMode, xiSelectedMetadata));
            }
              }

              /////////////////////////////////////////////////////
              // The child objects
              if (Objects != null)
              {
            foreach (ObjectEntry oe in Objects)
            {
              lAcc.AddRange(oe.GetEntities(xiLevel, xiTextureMode, xiSelectedMetadata));
            }
              }

              return lAcc;
        }
예제 #5
0
        private GLTK.Entity GetSurfaceEntity(Level xiLevel, eTextureMode xiTextureMode, eTexMetaDataEntries xiSelectedMetadata)
        {
            // notes:
              // invert the textures along the y-axis
              // use level co-ords, so z is down

              /////////////////////////////////////////////////////
              // The surface
              Entity lSurface = new MMEdEntity(this);

              Font lNumberFont = null;
              Brush lNumberFGBrush = null, lNumberBGBrush = null;
              Pen lWaypointPen = null, lKeyWaypointPen = null;
              if (xiTextureMode == eTextureMode.NormalTexturesWithMetadata)
              {
            lNumberFont = new Font(FontFamily.GenericMonospace, 10);
            lNumberFGBrush = new SolidBrush(Color.Black);
            lNumberBGBrush = new SolidBrush(Color.White);
            lWaypointPen = new Pen(Color.Black, 1f);
            lKeyWaypointPen = new Pen(Color.Red, 2f);
              }

              for (int x = 0; x < Width; x++)
              {
            for (int y = 0; y < Height; y++)
            {
              Mesh lSquare = new OwnedMesh(this, PolygonMode.Quads);
              lSquare.AddFace(
            new Vertex(new Point(x, y, -GetTerrainHeightSafe(x, y)), 0, 0),
            new Vertex(new Point(x + 1, y, -GetTerrainHeightSafe(x + 1, y)), 1, 0),
            new Vertex(new Point(x + 1, y + 1, -GetTerrainHeightSafe(x + 1, y + 1)), 1, 1),
            new Vertex(new Point(x, y + 1, -GetTerrainHeightSafe(x, y + 1)), 0, 1));

              switch (xiTextureMode)
              {
            case eTextureMode.WireFrame:
              lSquare.RenderMode = RenderMode.Wireframe;
              break;

            // normal textures, optionally with metadata drawn on
            case eTextureMode.NormalTextures:
            case eTextureMode.NormalTexturesWithMetadata:
              TIMChunk lTIM = xiLevel.GetTileById(TextureIds[x][y]);

              if (lTIM != null)
              {
                //some TIMs can't be loaded yet: they're null
                Bitmap lTexture = lTIM.ToBitmap();
                if (xiTextureMode == eTextureMode.NormalTexturesWithMetadata
                    && TexMetaData != null)
                {
                  byte lVal = TexMetaData[x][y][(int)xiSelectedMetadata];

                  if (lVal != 0)
                  {
                    // we create a new bitmap based on the given texture
                    // a) so that we can modify it freely
                    // and b) to change it from indexed to full colour mode, to allow us
                    // to draw on it (otherwise we'll get an exception)
                    lTexture = new Bitmap(lTexture);

                    Graphics g = Graphics.FromImage(lTexture);

                    string lText = lVal.ToString();

                    SizeF size = g.MeasureString(lText, lNumberFont);

                    float xf = lTexture.Width / 2.0f - size.Width / 2.0f;
                    float yf = lTexture.Height / 2.0f - size.Height / 2.0f;

                    g.FillRectangle(lNumberBGBrush, xf, yf, size.Width, size.Height);

                    g.DrawString(
                        lText,
                        lNumberFont,
                        lNumberFGBrush,
                        xf,
                        yf);

                    if (xiSelectedMetadata == eTexMetaDataEntries.Waypoint)
                    {
                      Pen lPen = xiLevel.WaypointIsKeyWaypoint(lVal)
                          ? lKeyWaypointPen
                          : lWaypointPen;

                      g.DrawRectangle(
                          lPen,
                          0, 0, lTexture.Width - 1, lTexture.Height - 1);

                    }
                  }
                }

                lSquare.Texture = AbstractRenderer.ImageToTextureId(lTexture);
              }
              break;

            //draw the bumpmap textures on:
            case eTextureMode.BumpmapTextures:
              if (TexMetaData != null)
              {
                BumpImageChunk lBIC = xiLevel.GetBumpById(TexMetaData[x][y][(int)eTexMetaDataEntries.Bumpmap]);

                if (lBIC != null)
                {
                  Bitmap lTexture = lBIC.ToBitmap();
                  lSquare.Texture = AbstractRenderer.ImageToTextureId(lTexture);
                }
              }
              break;

            default: throw new Exception("Unexpected case");

              } //end switch

              lSurface.Meshes.Add(lSquare);
            }
              }

              lSurface.Scale(ScaleX, ScaleY, 1.0);
              if (RotationVector.Norm() != 0)
              {
            //the rotation is z-y-x
            lSurface.RotateAboutWorldOrigin(RotationVector.Z / 1024.0 * Math.PI / 2.0, Vector.ZAxis);
            lSurface.RotateAboutWorldOrigin(-RotationVector.Y / 1024.0 * Math.PI / 2.0, Vector.YAxis);
            lSurface.RotateAboutWorldOrigin(-RotationVector.X / 1024.0 * Math.PI / 2.0, Vector.XAxis);
              }

              Point lNewPos = ThreeDeeViewer.Short3CoordToPoint(OriginPosition);
              lSurface.Position = new Point(lNewPos.x, lNewPos.y, -lNewPos.z);

              return lSurface;
        }
예제 #6
0
 public IEnumerable<GLTK.Entity> GetEntities(Chunk xiRootChunk, eTextureMode xiTextureMode, eTexMetaDataEntries xiSelectedMetadata)
 {
     return SHET.GetEntities(xiRootChunk, xiTextureMode, xiSelectedMetadata);
 }
예제 #7
0
            public IEnumerable <GLTK.Entity> GetEntities(Chunk xiRootChunk, eTextureMode xiTextureMode, eTexMetaDataEntries xiSelectedMetadata)
            {
                //a bit hacky:
                if (this.TreeNode.Checked)
                {
                    return(new Entity[0]);
                }

                Entity lWeaponEntity = ((Level)xiRootChunk).GetObjtById(TMDChunk.OBJT_ID_FOR_WEAPONS_BOX)
                                       .GetEntity(xiRootChunk, xiTextureMode, xiSelectedMetadata, this);

                // Set the position.
                Point lWeaponPosition = ThreeDeeViewer.Short3CoordToPoint(this.OriginPosition);

                lWeaponEntity.Position = new Point(lWeaponPosition.x, lWeaponPosition.y, -lWeaponPosition.z);

                List <GLTK.Entity> lRet = new List <Entity>();

                lRet.Add(lWeaponEntity);
                return(lRet);
            }
예제 #8
0
        public Entity GetEntity(Chunk xiRootChunk, eTextureMode xiTextureMode, eTexMetaDataEntries xiSelectedMetadata, object xiMeshOwner)
        {
            MMEdEntity lAcc = new MMEdEntity(xiMeshOwner);
              Mesh lColouredMesh = null;
              Dictionary<int, Mesh> lPageIdToTexturedMeshMap = new Dictionary<int, Mesh>();
              List<Mesh> lTranslucentMeshes = new List<Mesh>();

              //qq move all this into Face class?
              //qq add quad mode meshes (needs separate meshes currently...)
              Vertex[] lVBuff = new Vertex[4];
              foreach (Face f in Faces)
              {
            if (!f.IsUnknownType())
            {
              for (int v = 0; v < f.mVertexIds.Length; v++)
              {
            lVBuff[v] = new Vertex(ThreeDeeViewer.Short3CoordToPoint(Vertices[f.mVertexIds[v]]));

            //normal
            if (v < f.mNormalIds.Length)
              lVBuff[v].Normal = ThreeDeeViewer.Short3CoordToPoint(Normals[f.mNormalIds[v]]).GetPositionVector().Normalise();
            else lVBuff[v].Normal = ThreeDeeViewer.Short3CoordToPoint(Normals[f.mNormalIds[0]]).GetPositionVector().Normalise();

            //color:
            if (f.mColors != null && v < f.mColors.Length)
              lVBuff[v].Color = Utils.PSRGBColorToColor(f.mColors[v]);
            else if (f.mColors != null)
              lVBuff[v].Color = Utils.PSRGBColorToColor(f.mColors[0]);

            //tex coords
            if (f.mTexCoords != null && v < f.mTexCoords.Length)
            {
              lVBuff[v].TexCoordX = f.mTexCoords[v].X / (double)VRAMViewer.TEX_PAGE_WIDTH;
              lVBuff[v].TexCoordY = f.mTexCoords[v].Y / (double)VRAMViewer.TEX_PAGE_HEIGHT;
            }
              }

              // Create a new mesh if appropriate, or add this face to an existing mesh
              // First check if it's tex or solid?
              Mesh lMesh;
              if (f.mTexCoords != null)
              {
            if (!lPageIdToTexturedMeshMap.ContainsKey(f.mTexPage))
            {
              lMesh = new OwnedMesh(xiMeshOwner);
              lPageIdToTexturedMeshMap[f.mTexPage] = lMesh;

              if (xiTextureMode == eTextureMode.NormalTextures
                || xiTextureMode == eTextureMode.NormalTexturesWithMetadata)
              {
                lMesh.RenderMode = RenderMode.Textured;
                lMesh.Texture = AbstractRenderer.ImageToTextureId(
                  VRAMViewer.GetInstance().GetTexturePage(xiRootChunk, f.mTexPage));
              }
              else
              {
                lMesh.RenderMode = RenderMode.Wireframe;
              }
            }
            else
            {
              lMesh = lPageIdToTexturedMeshMap[f.mTexPage];
            }
              }
              else
              {
            if (f.IsTranslucent())
            {
              lMesh = new OwnedMesh(xiMeshOwner);
              if (xiTextureMode == eTextureMode.NormalTextures
                || xiTextureMode == eTextureMode.NormalTexturesWithMetadata)
              {
                lMesh.RenderMode = RenderMode.TranslucentFilled;
              }
              else
              {
                lMesh.RenderMode = RenderMode.Wireframe;
              }
              lTranslucentMeshes.Add(lMesh);
            }
            else
            {
              if (lColouredMesh == null)
              {
                lColouredMesh = new OwnedMesh(xiMeshOwner);

                if (xiTextureMode == eTextureMode.NormalTextures
                  || xiTextureMode == eTextureMode.NormalTexturesWithMetadata)
                {
                  lColouredMesh.RenderMode = RenderMode.Filled;
                }
                else
                {
                  lColouredMesh.RenderMode = RenderMode.Wireframe;
                }
              }
              lMesh = lColouredMesh;
            }
              }

              if (f.mVertexIds.Length == 3)
              {
            lMesh.AddFace(lVBuff[0], lVBuff[1], lVBuff[2]);
              }
              else //4
              {
            lMesh.AddFace(lVBuff[0], lVBuff[1], lVBuff[2]);
            lMesh.AddFace(lVBuff[0], lVBuff[2], lVBuff[3]);
              }
            }
              }

              foreach (Mesh lTexturedMesh in lPageIdToTexturedMeshMap.Values)
              {
            lAcc.Meshes.Add(lTexturedMesh);
              }
              if (lColouredMesh != null) lAcc.Meshes.Add(lColouredMesh);
              lAcc.Meshes.AddRange(lTranslucentMeshes);

              lAcc.Scale(1, 1, -1);

              return lAcc;
        }
예제 #9
0
            public IEnumerable<GLTK.Entity> GetEntities(Chunk xiRootChunk, eTextureMode xiTextureMode, eTexMetaDataEntries xiSelectedMetadata)
            {
                //a bit hacky:
                if (this.TreeNode.Checked)
                {
                  return new Entity[0];
                }

                List<GLTK.Entity> lRet = new List<Entity>();
                TMDChunk lObjt = ((Level)xiRootChunk).GetObjtById(this.ObjtType);
                if (lObjt != null)
                {
                  Entity lE = lObjt.GetEntity(xiRootChunk, xiTextureMode, xiSelectedMetadata, this);

                  //nasty, but required because the PS 3D world coords are left-handed,
                  //and the OpenGl 3D coords are right handed
                  lE.Scale(1, 1, -1);

                  if (this.RotationVector.Norm() != 0)
                  {
                //the rotation is z-y-x
                lE.RotateAboutWorldOrigin(-this.RotationVector.Z / 1024.0 * Math.PI / 2.0, Vector.ZAxis);
                lE.RotateAboutWorldOrigin(-this.RotationVector.Y / 1024.0 * Math.PI / 2.0, Vector.YAxis);
                lE.RotateAboutWorldOrigin(-this.RotationVector.X / 1024.0 * Math.PI / 2.0, Vector.XAxis);
                  }

                  lE.Position = ThreeDeeViewer.Short3CoordToPoint(this.OriginPosition);

                  //return to right handed coords
                  lE.Scale(1, 1, -1);

                  lRet.Add(lE);
                }

                return lRet;
            }
예제 #10
0
        public IEnumerable<GLTK.Entity> GetEntities(Chunk xiRootChunk, eTextureMode xiTextureMode, eTexMetaDataEntries xiSelectedMetadata)
        {
            if (!(xiRootChunk is Level))
              {
            throw new Exception("xiRootChunk must be Level for SHETChunk.GetEntities");
              }

              List<Entity> lAcc = new List<Entity>();

              foreach (FlatChunk fl in Flats)
              {
            lAcc.AddRange(fl.GetEntities((Level)xiRootChunk, xiTextureMode, xiSelectedMetadata));
              }

              return lAcc;
        }
예제 #11
0
 public IEnumerable<GLTK.Entity> GetEntities(Chunk xiRootChunk, eTextureMode xiTextureMode, eTexMetaDataEntries xiSelectedMetadata)
 {
     return new Entity[] { GetEntity(xiRootChunk, xiTextureMode, xiSelectedMetadata, this) };
 }
예제 #12
0
        private GLTK.Entity GetSurfaceEntity(Level xiLevel, eTextureMode xiTextureMode, eTexMetaDataEntries xiSelectedMetadata)
        {
            // notes:
            // invert the textures along the y-axis
            // use level co-ords, so z is down

            /////////////////////////////////////////////////////
            // The surface
            Entity lSurface = new MMEdEntity(this);

            Font  lNumberFont = null;
            Brush lNumberFGBrush = null, lNumberBGBrush = null;
            Pen   lWaypointPen = null, lKeyWaypointPen = null;

            if (xiTextureMode == eTextureMode.NormalTexturesWithMetadata)
            {
                lNumberFont     = new Font(FontFamily.GenericMonospace, 10);
                lNumberFGBrush  = new SolidBrush(Color.Black);
                lNumberBGBrush  = new SolidBrush(Color.White);
                lWaypointPen    = new Pen(Color.Black, 1f);
                lKeyWaypointPen = new Pen(Color.Red, 2f);
            }

            for (int x = 0; x < Width; x++)
            {
                for (int y = 0; y < Height; y++)
                {
                    Mesh lSquare = new OwnedMesh(this, PolygonMode.Quads);
                    lSquare.AddFace(
                        new Vertex(new Point(x, y, -GetTerrainHeightSafe(x, y)), 0, 0),
                        new Vertex(new Point(x + 1, y, -GetTerrainHeightSafe(x + 1, y)), 1, 0),
                        new Vertex(new Point(x + 1, y + 1, -GetTerrainHeightSafe(x + 1, y + 1)), 1, 1),
                        new Vertex(new Point(x, y + 1, -GetTerrainHeightSafe(x, y + 1)), 0, 1));

                    switch (xiTextureMode)
                    {
                    case eTextureMode.WireFrame:
                        lSquare.RenderMode = RenderMode.Wireframe;
                        break;

                    // normal textures, optionally with metadata drawn on
                    case eTextureMode.NormalTextures:
                    case eTextureMode.NormalTexturesWithMetadata:
                        TIMChunk lTIM = xiLevel.GetTileById(TextureIds[x][y]);

                        if (lTIM != null)
                        {
                            //some TIMs can't be loaded yet: they're null
                            Bitmap lTexture = lTIM.ToBitmap();
                            if (xiTextureMode == eTextureMode.NormalTexturesWithMetadata &&
                                TexMetaData != null)
                            {
                                byte lVal = TexMetaData[x][y][(int)xiSelectedMetadata];

                                if (lVal != 0)
                                {
                                    // we create a new bitmap based on the given texture
                                    // a) so that we can modify it freely
                                    // and b) to change it from indexed to full colour mode, to allow us
                                    // to draw on it (otherwise we'll get an exception)
                                    lTexture = new Bitmap(lTexture);

                                    Graphics g = Graphics.FromImage(lTexture);

                                    string lText = lVal.ToString();

                                    SizeF size = g.MeasureString(lText, lNumberFont);

                                    float xf = lTexture.Width / 2.0f - size.Width / 2.0f;
                                    float yf = lTexture.Height / 2.0f - size.Height / 2.0f;

                                    g.FillRectangle(lNumberBGBrush, xf, yf, size.Width, size.Height);

                                    g.DrawString(
                                        lText,
                                        lNumberFont,
                                        lNumberFGBrush,
                                        xf,
                                        yf);

                                    if (xiSelectedMetadata == eTexMetaDataEntries.Waypoint)
                                    {
                                        Pen lPen = xiLevel.WaypointIsKeyWaypoint(lVal)
                          ? lKeyWaypointPen
                          : lWaypointPen;

                                        g.DrawRectangle(
                                            lPen,
                                            0, 0, lTexture.Width - 1, lTexture.Height - 1);
                                    }
                                }
                            }

                            lSquare.Texture = AbstractRenderer.ImageToTextureId(lTexture);
                        }
                        break;

                    //draw the bumpmap textures on:
                    case eTextureMode.BumpmapTextures:
                        if (TexMetaData != null)
                        {
                            BumpImageChunk lBIC = xiLevel.GetBumpById(TexMetaData[x][y][(int)eTexMetaDataEntries.Bumpmap]);

                            if (lBIC != null)
                            {
                                Bitmap lTexture = lBIC.ToBitmap();
                                lSquare.Texture = AbstractRenderer.ImageToTextureId(lTexture);
                            }
                        }
                        break;

                    default: throw new Exception("Unexpected case");
                    } //end switch

                    lSurface.Meshes.Add(lSquare);
                }
            }

            lSurface.Scale(ScaleX, ScaleY, 1.0);
            if (RotationVector.Norm() != 0)
            {
                //the rotation is z-y-x
                lSurface.RotateAboutWorldOrigin(RotationVector.Z / 1024.0 * Math.PI / 2.0, Vector.ZAxis);
                lSurface.RotateAboutWorldOrigin(-RotationVector.Y / 1024.0 * Math.PI / 2.0, Vector.YAxis);
                lSurface.RotateAboutWorldOrigin(-RotationVector.X / 1024.0 * Math.PI / 2.0, Vector.XAxis);
            }

            Point lNewPos = ThreeDeeViewer.Short3CoordToPoint(OriginPosition);

            lSurface.Position = new Point(lNewPos.x, lNewPos.y, -lNewPos.z);

            return(lSurface);
        }
예제 #13
0
        public IEnumerable <GLTK.Entity> GetEntities(Level xiLevel, eTextureMode xiTextureMode, eTexMetaDataEntries xiSelectedMetadata)
        {
            List <Entity> lAcc = new List <Entity>();

            //a bit hacky:
            if (!this.TreeNode.Checked)
            {
                lAcc.Add(GetSurfaceEntity(xiLevel, xiTextureMode, xiSelectedMetadata));
            }

            /////////////////////////////////////////////////////
            // The child weapons
            if (Weapons != null)
            {
                foreach (WeaponEntry lWeapon in Weapons)
                {
                    lAcc.AddRange(lWeapon.GetEntities(xiLevel, xiTextureMode, xiSelectedMetadata));
                }
            }

            /////////////////////////////////////////////////////
            // The child objects
            if (Objects != null)
            {
                foreach (ObjectEntry oe in Objects)
                {
                    lAcc.AddRange(oe.GetEntities(xiLevel, xiTextureMode, xiSelectedMetadata));
                }
            }

            return(lAcc);
        }
예제 #14
0
        public IEnumerable <GLTK.Entity> GetEntities(Chunk xiRootChunk, eTextureMode xiTextureMode, eTexMetaDataEntries xiSelectedMetadata)
        {
            if (!(xiRootChunk is Level))
            {
                throw new Exception("xiRootChunk must be Level for Level.GetEntities");
            }

            return(GetEntities((Level)xiRootChunk, xiTextureMode, xiSelectedMetadata));
        }
예제 #15
0
        ///========================================================================
        /// Method : CompactImages
        ///
        /// <summary>
        ///     Compact images fo the given type - remove any unused images from the
        ///   end of the array.
        /// </summary>
        /// <param name="xiImageType"></param>
        /// <remarks>
        ///   Note that no attempt is made to deduplicate - it is assumed that
        ///   duplicates will be removed via ReindexImages if required.
        /// </remarks>
        ///========================================================================
        public void CompactImages(eTexMetaDataEntries xiImageType)
        {
            Level lLevel = mMainForm.CurrentLevel;

            if (lLevel == null)
            {
                MessageBox.Show("Must have a level open for this action");
                return;
            }

            //=======================================================================
            // Work out which array of images to work with
            //=======================================================================
            Chunk[] lChunkArray;
            if (xiImageType == eTexMetaDataEntries.Bumpmap)
            {
                lChunkArray = lLevel.SHET.BumpImages.mChildren;
            }
            else if (xiImageType == eTexMetaDataEntries.Steering)
            {
                lChunkArray = lLevel.SHET.SteeringImages.mChildren;
            }
            else if (xiImageType == eTexMetaDataEntries.CameraPos)
            {
                lChunkArray = lLevel.SHET.CameraPositions.mChildren;
            }
            else
            {
                throw new Exception("Internal error: Cannot reindex images of type " + xiImageType.ToString());
            }

            //=======================================================================
            // Find the highest numbered image that's in use - we'll remove all
            // higher-numbered images
            //=======================================================================
            int lMaxUsedIndex = -1;
            int lTexMetaIndex = (int)xiImageType;

            foreach (FlatChunk lFlat in lLevel.SHET.Flats)
            {
                if (lFlat.TexMetaData != null)
                {
                    foreach (byte[][] lRow in lFlat.TexMetaData)
                    {
                        foreach (byte[] lEntry in lRow)
                        {
                            if (lMaxUsedIndex < lEntry[lTexMetaIndex])
                            {
                                lMaxUsedIndex = lEntry[lTexMetaIndex];
                            }
                        }
                    }
                }
            }

            if (lMaxUsedIndex == -1)
            {
                MessageBox.Show(string.Format("No compaction required - there are no {0} tiles!",
                                              xiImageType.ToString().ToLower()));
                return;
            }

            //=======================================================================
            // Create a new image array and adjust zero padding
            //=======================================================================
            Chunk[] lNewChunkArray = new Chunk[lMaxUsedIndex + 1];
            Array.Copy(lChunkArray, lNewChunkArray, lMaxUsedIndex + 1);

            lLevel.SHET.TrailingZeroByteCount += (lChunkArray.Length - (lMaxUsedIndex + 1)) * ((IReindexableChunk)lChunkArray[0]).Data.Length;

            if (xiImageType == eTexMetaDataEntries.Bumpmap)
            {
                lLevel.SHET.BumpImages.mChildren = lNewChunkArray;
            }
            else if (xiImageType == eTexMetaDataEntries.Steering)
            {
                lLevel.SHET.SteeringImages.mChildren = lNewChunkArray;
            }
            else if (xiImageType == eTexMetaDataEntries.CameraPos)
            {
                lLevel.SHET.CameraPositions.mChildren = lNewChunkArray;
            }

            MessageBox.Show(string.Format("Successfully compacted. There are {0} {1} tiles remaining",
                                          lMaxUsedIndex + 1,
                                          xiImageType.ToString().ToLower()));
        }
예제 #16
0
            public IEnumerable<GLTK.Entity> GetEntities(Chunk xiRootChunk, eTextureMode xiTextureMode, eTexMetaDataEntries xiSelectedMetadata)
            {
                //a bit hacky:
                if (this.TreeNode.Checked)
                {
                  return new Entity[0];
                }

                Entity lWeaponEntity = ((Level)xiRootChunk).GetObjtById(TMDChunk.OBJT_ID_FOR_WEAPONS_BOX)
                  .GetEntity(xiRootChunk, xiTextureMode, xiSelectedMetadata, this);

                // Set the position.
                Point lWeaponPosition = ThreeDeeViewer.Short3CoordToPoint(this.OriginPosition);
                lWeaponEntity.Position = new Point(lWeaponPosition.x, lWeaponPosition.y, -lWeaponPosition.z);

                List<GLTK.Entity> lRet = new List<Entity>();
                lRet.Add(lWeaponEntity);
                return lRet;
            }
예제 #17
0
        ///========================================================================
        /// Method : ReindexImages
        ///
        /// <summary>
        ///     Reindex images of the given type - remove duplicates and renumber
        ///   to the top of the image array.
        /// </summary>
        /// <param name="xiImageType"></param>
        ///========================================================================
        public void ReindexImages(eTexMetaDataEntries xiImageType)
        {
            Level lLevel = mMainForm.CurrentLevel;

            if (lLevel == null)
            {
                MessageBox.Show("Must have a level open for this action");
                return;
            }

            Chunk[] lChunkArray;
            if (xiImageType == eTexMetaDataEntries.Bumpmap)
            {
                lChunkArray = lLevel.SHET.BumpImages.mChildren;
            }
            else if (xiImageType == eTexMetaDataEntries.Steering)
            {
                lChunkArray = lLevel.SHET.SteeringImages.mChildren;
            }
            else if (xiImageType == eTexMetaDataEntries.CameraPos)
            {
                lChunkArray = lLevel.SHET.CameraPositions.mChildren;
            }
            else
            {
                throw new Exception("Internal error: Cannot reindex images of type " + xiImageType.ToString());
            }

            // count how many times each image is currently in use
            int[] lUseCount     = new int[lChunkArray.Length];
            int   lTexMetaIndex = (int)xiImageType;

            foreach (FlatChunk flat in lLevel.SHET.Flats)
            {
                if (flat.TexMetaData != null)
                {
                    foreach (byte[][] row in flat.TexMetaData)
                    {
                        foreach (byte[] entry in row)
                        {
                            lUseCount[entry[lTexMetaIndex]]++;
                        }
                    }
                }
            }

            //get a mapping from each equivalence class of chunks to the lowest index in that class
            SortedDictionary <IReindexableChunk, int> lImagesToCanonicalId = new SortedDictionary <IReindexableChunk, int>(new ReindexableChunkComparer());

            for (int i = lChunkArray.Length - 1; i >= 0; i--)
            {
                if (lUseCount[i] == 0)
                {
                    // Ignore any unused images - otherwise we might try to remap used images
                    // to unused ones, which would cause errors when we remove all the unused
                    // images later on.
                    continue;
                }

                lImagesToCanonicalId[(IReindexableChunk)lChunkArray[i]] = i;
            }

            int[] lOldToNewIndexMap = new int[lUseCount.Length];

            //determine where each image should map to:
            int lNextUnusedId = 0;

            for (int lOldIdx = 0; lOldIdx < lOldToNewIndexMap.Length; lOldIdx++)
            {
                if (lUseCount[lOldIdx] > 0)
                {
                    //we need to map this to somewhere.
                    //can it be coalesced with other, identical bumps?
                    int lCanonicalId = (int)lImagesToCanonicalId[(IReindexableChunk)lChunkArray[lOldIdx]];
                    if (lCanonicalId < lOldIdx)
                    {
                        lOldToNewIndexMap[lOldIdx] = lOldToNewIndexMap[lCanonicalId];
                    }
                    else if (lCanonicalId == lOldIdx)
                    {
                        lOldToNewIndexMap[lOldIdx] = lNextUnusedId;
                        lNextUnusedId++;
                    }
                    else
                    {
                        throw new Exception("Internal error: lCanonicalId can't be greater than lOldIdx");
                    }
                }
                else
                {
                    lOldToNewIndexMap[lOldIdx] = -1;
                }
            }

            //take a copy of each canonical image, so we don't lose any information
            Dictionary <int, byte[]> lCanonicalImages = new Dictionary <int, byte[]>();

            foreach (KeyValuePair <IReindexableChunk, int> lEntry in lImagesToCanonicalId)
            {
                lCanonicalImages.Add(lEntry.Value, (byte[])lEntry.Key.Data.Clone());
            }

            //fill in all the bump images with their new values:
            int lHighestUsed = -1;

            for (int lOldIdx = 0; lOldIdx < lOldToNewIndexMap.Length; lOldIdx++)
            {
                int lNew = lOldToNewIndexMap[lOldIdx];
                if (lNew != -1)
                {
                    if (lCanonicalImages.ContainsKey(lOldIdx))
                    {
                        lHighestUsed = lNew;
                        ((IReindexableChunk)lChunkArray[lNew]).Data = lCanonicalImages[lOldIdx];
                    }
                }
            }
            for (int i = lHighestUsed + 1; i < lChunkArray.Length; i++)
            {
                ((IReindexableChunk)lChunkArray[i]).Clear();
            }

            //now update all the bumps in the Flats
            foreach (FlatChunk flat in lLevel.SHET.Flats)
            {
                if (flat.TexMetaData != null)
                {
                    foreach (byte[][] row in flat.TexMetaData)
                    {
                        foreach (byte[] entry in row)
                        {
                            int lOldIdx = entry[lTexMetaIndex];
                            int lNewIdx = lOldToNewIndexMap[lOldIdx];
                            if (lNewIdx < 0)
                            {
                                throw new Exception("Internal error: this image should be unused");
                            }
                            entry[lTexMetaIndex] = (byte)lNewIdx;
                        }
                    }
                }
            }

            MessageBox.Show(string.Format(
                                "Successfully reindexed. There are {0} {2} tiles in use, and {1} free",
                                lCanonicalImages.Count,
                                lChunkArray.Length - lCanonicalImages.Count,
                                xiImageType.ToString().ToLower()));
        }
예제 #18
0
        public IEnumerable<GLTK.Entity> GetEntities(Chunk xiRootChunk, eTextureMode xiTextureMode, eTexMetaDataEntries xiSelectedMetadata)
        {
            if (!(xiRootChunk is Level))
              {
            throw new Exception("xiRootChunk must be Level for Level.GetEntities");
              }

              return GetEntities((Level)xiRootChunk, xiTextureMode, xiSelectedMetadata);
        }
예제 #19
0
        public IEnumerable <GLTK.Entity> GetEntities(Chunk xiRootChunk, eTextureMode xiTextureMode, eTexMetaDataEntries xiSelectedMetadata)
        {
            if (!(xiRootChunk is Level))
            {
                throw new Exception("xiRootChunk must be Level for SHETChunk.GetEntities");
            }

            List <Entity> lAcc = new List <Entity>();

            foreach (FlatChunk fl in Flats)
            {
                lAcc.AddRange(fl.GetEntities((Level)xiRootChunk, xiTextureMode, xiSelectedMetadata));
            }

            return(lAcc);
        }
예제 #20
0
            public IEnumerable <GLTK.Entity> GetEntities(Chunk xiRootChunk, eTextureMode xiTextureMode, eTexMetaDataEntries xiSelectedMetadata)
            {
                //a bit hacky:
                if (this.TreeNode.Checked)
                {
                    return(new Entity[0]);
                }

                List <GLTK.Entity> lRet  = new List <Entity>();
                TMDChunk           lObjt = ((Level)xiRootChunk).GetObjtById(this.ObjtType);

                if (lObjt != null)
                {
                    Entity lE = lObjt.GetEntity(xiRootChunk, xiTextureMode, xiSelectedMetadata, this);

                    //nasty, but required because the PS 3D world coords are left-handed,
                    //and the OpenGl 3D coords are right handed
                    lE.Scale(1, 1, -1);

                    if (this.RotationVector.Norm() != 0)
                    {
                        //the rotation is z-y-x
                        lE.RotateAboutWorldOrigin(-this.RotationVector.Z / 1024.0 * Math.PI / 2.0, Vector.ZAxis);
                        lE.RotateAboutWorldOrigin(-this.RotationVector.Y / 1024.0 * Math.PI / 2.0, Vector.YAxis);
                        lE.RotateAboutWorldOrigin(-this.RotationVector.X / 1024.0 * Math.PI / 2.0, Vector.XAxis);
                    }

                    lE.Position = ThreeDeeViewer.Short3CoordToPoint(this.OriginPosition);

                    //return to right handed coords
                    lE.Scale(1, 1, -1);

                    lRet.Add(lE);
                }

                return(lRet);
            }