Cleanup in TextureAtlas2D, rename TextureAtlas2D to TerrainAtlas2D, move Vector3I to own file.

This commit is contained in:
UnknownShadow200 2015-05-27 17:57:39 +10:00
parent e2289b1a92
commit d65ba5b226
14 changed files with 286 additions and 339 deletions

View file

@ -31,7 +31,7 @@ namespace ClassicalSharp {
public override void Render( double delta ) {
GraphicsApi.Texturing = true;
GraphicsApi.Bind2DTexture( Window.TerrainAtlasTexId );
GraphicsApi.Bind2DTexture( Window.TerrainAtlas.TexId );
for( int i = 0; i < blocksTable.Length; i++ ) {
Texture texture = blocksTable[i].Texture;
@ -146,7 +146,7 @@ namespace ClassicalSharp {
float height = Window.BlockInfo.BlockHeight( (byte)block );
int blockY = y;
if( height != 1 ) {
rec.V1 = rec.V1 + Window.TerrainAtlas.invVerElementSize * height;
rec.V1 = rec.V1 + TerrainAtlas2D.invElementSize * height;
verSize = (int)( blockSize * height );
blockY = y + blockSize - verSize;
}

View file

@ -50,7 +50,7 @@ namespace ClassicalSharp {
public override void Render( double delta ) {
GraphicsApi.Texturing = true;
// TODO: Maybe redesign this so we don't have to bind the whole atlas. Not cheap.
GraphicsApi.Bind2DTexture( Window.TerrainAtlasTexId );
GraphicsApi.Bind2DTexture( Window.TerrainAtlas.TexId );
int selectedX = 0;
for( int i = 0; i < barTextures.Length; i++ ) {
barTextures[i].RenderNoBind( GraphicsApi );
@ -83,7 +83,7 @@ namespace ClassicalSharp {
float height = Window.BlockInfo.BlockHeight( (byte)block );
int blockY = y;
if( height != 1 ) {
rec.V1 = rec.V1 + Window.TerrainAtlas.invVerElementSize * height;
rec.V1 = rec.V1 + TerrainAtlas2D.invElementSize * height;
verSize = (int)( blockSize * height );
blockY = y + blockSize - verSize;
}

View file

@ -131,46 +131,5 @@ namespace ClassicalSharp {
public int GetOptimTextureLoc( byte block, int face ) {
return optimTextures[block * 6 + face];
}
static ushort[] RowFlags = new ushort[] {
0xFFFF, // y y y y y y y y y y y y y y y y
0xFFEE, // y y y y y y y y y y y n y y y n
0xFFE0, // y y y y y y y y y y y n n n n n
0xFFE0, // y y y y y y y y y y y n n n n n
0xFFFF, // y y y y y y y y y y y y y y y y
0xFA00, // y y y y y n y n n n n n n n n n
};
public static void MakeOptimisedTexture( FastBitmap atlas ) {
int tileSize = atlas.Width / 16;
int srcIndex = 0, destIndex = 0;
for( int y = 0; y < 6; y++ ) {
int flags = RowFlags[y];
for( int x = 0; x < 16; x++ ) {
bool isUsed = ( flags & 1 << ( 15 - x ) ) != 0;
if( isUsed && srcIndex != destIndex ) {
int srcX = x * tileSize;
int srcY = y * tileSize;
int destX = ( destIndex & 0x0F ) * tileSize;
int destY = ( destIndex >> 4 ) * tileSize;
MovePortion( srcX, srcY, destX, destY, atlas, tileSize );
}
srcIndex++;
if( isUsed ) destIndex++;
}
}
}
unsafe static void MovePortion( int srcX, int srcY, int dstX, int dstY, FastBitmap src, int size ) {
for( int y = 0; y < size; y++ ) {
int* srcRow = src.GetRowPtr( srcY + y );
int* dstRow = src.GetRowPtr( dstY + y );
for( int x = 0; x < size; x++ ) {
dstRow[dstX + x] = srcRow[srcX + x];
}
}
}
}
}

View file

@ -153,9 +153,11 @@
<Compile Include="Utils\FastBitmap.cs" />
<Compile Include="Utils\FastColour.cs" />
<Compile Include="Utils\TextureAtlas1D.cs" />
<Compile Include="Utils\TextureAtlas2D.cs" />
<Compile Include="Utils\TerrainAtlas2D.cs" />
<Compile Include="Utils\TextureRectangle.cs" />
<Compile Include="Utils\UnsafeString.cs" />
<Compile Include="Utils\Utils.cs" />
<Compile Include="Utils\Vector3I.cs" />
</ItemGroup>
<ItemGroup>
<BootstrapperPackage Include=".NETFramework,Version=v4.0">

View file

@ -30,7 +30,7 @@ namespace ClassicalSharp.Particles {
}
Graphics.Texturing = true;
Graphics.Bind2DTexture( Window.TerrainAtlasTexId );
Graphics.Bind2DTexture( Window.TerrainAtlas.TexId );
Graphics.AlphaTest = true;
Graphics.DrawVertices( DrawMode.Triangles, vertices, count );
Graphics.AlphaTest = false;
@ -54,8 +54,8 @@ namespace ClassicalSharp.Particles {
int texLoc = Window.BlockInfo.GetOptimTextureLoc( block, TileSide.Left );
TextureRectangle rec = Window.TerrainAtlas.GetTexRec( texLoc );
float invHorSize = Window.TerrainAtlas.invHorElementSize;
float invVerSize = Window.TerrainAtlas.invVerElementSize;
float invHorSize = TerrainAtlas2D.invElementSize;
float invVerSize = TerrainAtlas2D.invElementSize;
int cellsCountX = (int)( 0.25f / invHorSize );
int cellsCountY = (int)( 0.25f / invVerSize );
float elementXSize = invHorSize * 0.25f;

View file

@ -28,8 +28,7 @@ namespace ClassicalSharp {
Camera firstPersonCam, thirdPersonCam;
public BlockInfo BlockInfo;
public double accumulator;
public TextureAtlas2D TerrainAtlas;
public int TerrainAtlasTexId = -1;
public TerrainAtlas2D TerrainAtlas;
public TextureAtlas1D TerrainAtlas1D;
public int[] TerrainAtlas1DTexIds;
public SkinType DefaultPlayerSkinType;
@ -97,21 +96,14 @@ namespace ClassicalSharp {
void LoadAtlas( Bitmap bmp ) {
// Cleanup old atlas if applicable.
Graphics.DeleteTexture( ref TerrainAtlasTexId );
if( TerrainAtlas1DTexIds != null ) {
for( int i = 0; i < TerrainAtlas1DTexIds.Length; i++ ) {
Graphics.DeleteTexture( ref TerrainAtlas1DTexIds[i] );
}
}
if( TerrainAtlas != null ) {
TerrainAtlas.AtlasBitmap.Dispose();
}
TerrainAtlas = new TextureAtlas2D( Graphics, bmp, 16, 16, 5 );
using( FastBitmap fastBmp = new FastBitmap( bmp, true ) ) {
BlockInfo.MakeOptimisedTexture( fastBmp );
TerrainAtlasTexId = Graphics.LoadTexture( fastBmp );
}
TerrainAtlas.GraphicsApi = Graphics;
TerrainAtlas.Dispose();
TerrainAtlas.UpdateState( bmp );
int size = Math.Min( 2048, Graphics.MaxTextureDimensions );
TerrainAtlas1DTexIds = TerrainAtlas1D.CreateFrom2DAtlas( Graphics, TerrainAtlas, size );
}
@ -136,6 +128,7 @@ namespace ClassicalSharp {
PrintGraphicsInfo();
Bitmap terrainBmp = new Bitmap( "terrain.png" );
TerrainAtlas1D = new TextureAtlas1D();
TerrainAtlas = new TerrainAtlas2D();
LoadAtlas( terrainBmp );
BlockInfo = new BlockInfo();
BlockInfo.Init();
@ -290,7 +283,7 @@ namespace ClassicalSharp {
SetNewScreen( null );
fpsScreen.Dispose();
SelectionManager.Dispose();
Graphics.DeleteTexture( ref TerrainAtlasTexId );
TerrainAtlas.Dispose();
for( int i = 0; i < TerrainAtlas1DTexIds.Length; i++ ) {
Graphics.DeleteTexture( ref TerrainAtlas1DTexIds[i] );
}

View file

@ -201,8 +201,7 @@ namespace ClassicalSharp {
void DrawTopFace( int count ) {
int texId = BlockInfo.GetOptimTextureLoc( tile, TileSide.Top );
int drawInfoIndex;
TextureRectangle rec = atlas.GetTexRec( texId, out drawInfoIndex );
rec.U2 = count;
TextureRectangle rec = atlas.GetTexRec( texId, count, out drawInfoIndex );
FastColour col = GetColour( X, Y + 1, Z, ref map.Sunlight, ref map.Shadowlight );
if( blockHeight == -1 ) {
blockHeight = BlockInfo.BlockHeight( tile );
@ -221,8 +220,7 @@ namespace ClassicalSharp {
void DrawBottomFace( int count ) {
int texId = BlockInfo.GetOptimTextureLoc( tile, TileSide.Bottom );
int drawInfoIndex;
TextureRectangle rec = atlas.GetTexRec( texId, out drawInfoIndex );
rec.U2 = count;
TextureRectangle rec = atlas.GetTexRec( texId, count, out drawInfoIndex );
FastColour col = GetColour( X, Y - 1, Z, ref map.SunlightYBottom, ref map.ShadowlightYBottom );
if( blockHeight == -1 ) {
blockHeight = BlockInfo.BlockHeight( tile );
@ -241,8 +239,7 @@ namespace ClassicalSharp {
void DrawBackFace( int count ) {
int texId = BlockInfo.GetOptimTextureLoc( tile, TileSide.Back );
int drawInfoIndex;
TextureRectangle rec = atlas.GetTexRec( texId, out drawInfoIndex );
rec.U2 = count;
TextureRectangle rec = atlas.GetTexRec( texId, count, out drawInfoIndex );
FastColour col = GetColourAdj( X, Y, Z + 1, ref map.SunlightZSide, ref map.ShadowlightZSide );
if( blockHeight == -1 ) {
blockHeight = BlockInfo.BlockHeight( tile );
@ -264,8 +261,7 @@ namespace ClassicalSharp {
void DrawFrontFace( int count ) {
int texId = BlockInfo.GetOptimTextureLoc( tile, TileSide.Front );
int drawInfoIndex;
TextureRectangle rec = atlas.GetTexRec( texId, out drawInfoIndex );
rec.U2 = count;
TextureRectangle rec = atlas.GetTexRec( texId, count, out drawInfoIndex );
FastColour col = GetColourAdj( X, Y, Z - 1, ref map.SunlightZSide, ref map.ShadowlightZSide );
if( blockHeight == -1 ) {
blockHeight = BlockInfo.BlockHeight( tile );
@ -287,8 +283,7 @@ namespace ClassicalSharp {
void DrawLeftFace( int count ) {
int texId = BlockInfo.GetOptimTextureLoc( tile, TileSide.Left );
int drawInfoIndex;
TextureRectangle rec = atlas.GetTexRec( texId, out drawInfoIndex );
rec.U2 = count;
TextureRectangle rec = atlas.GetTexRec( texId, count, out drawInfoIndex );
FastColour col = GetColourAdj( X - 1, Y, Z, ref map.SunlightXSide, ref map.ShadowlightXSide );
if( blockHeight == -1 ) {
blockHeight = BlockInfo.BlockHeight( tile );
@ -310,8 +305,7 @@ namespace ClassicalSharp {
void DrawRightFace( int count ) {
int texId = BlockInfo.GetOptimTextureLoc( tile, TileSide.Right );
int drawInfoIndex;
TextureRectangle rec = atlas.GetTexRec( texId, out drawInfoIndex );
rec.U2 = count;
TextureRectangle rec = atlas.GetTexRec( texId, count, out drawInfoIndex );
FastColour col = GetColourAdj( X + 1, Y, Z, ref map.SunlightXSide, ref map.ShadowlightXSide );
if( blockHeight == -1 ) {
blockHeight = BlockInfo.BlockHeight( tile );
@ -333,8 +327,7 @@ namespace ClassicalSharp {
void DrawSprite( int count ) {
int texId = BlockInfo.GetOptimTextureLoc( tile, TileSide.Right );
int drawInfoIndex;
TextureRectangle rec = atlas.GetTexRec( texId, out drawInfoIndex );
rec.U2 = count;
TextureRectangle rec = atlas.GetTexRec( texId, count, out drawInfoIndex );
FastColour col = GetColour( X, Y + 1, Z, ref map.Sunlight, ref map.Shadowlight );
if( blockHeight == -1 ) {
blockHeight = BlockInfo.BlockHeight( tile );

View file

@ -26,7 +26,7 @@ namespace ClassicalSharp.Model {
return;
}
graphics.Bind2DTexture( window.TerrainAtlasTexId );
graphics.Bind2DTexture( window.TerrainAtlas.TexId );
blockHeight = window.BlockInfo.BlockHeight( block );
atlas = window.TerrainAtlas;
BlockInfo = window.BlockInfo;
@ -46,7 +46,7 @@ namespace ClassicalSharp.Model {
}
}
float blockHeight;
TextureAtlas2D atlas;
TerrainAtlas2D atlas;
BlockInfo BlockInfo;
public override void Dispose() {
@ -69,7 +69,7 @@ namespace ClassicalSharp.Model {
int texId = BlockInfo.GetOptimTextureLoc( block, side );
TextureRectangle rec = atlas.GetTexRec( texId );
if( blockHeight != 1 ) {
rec.V2 = rec.V1 + blockHeight * atlas.invVerElementSize;
rec.V2 = rec.V1 + blockHeight * TerrainAtlas2D.invElementSize;
}
if( swapU ) rec.SwapU();
@ -86,7 +86,7 @@ namespace ClassicalSharp.Model {
int texId = BlockInfo.GetOptimTextureLoc( block, side );
TextureRectangle rec = atlas.GetTexRec( texId );
if( blockHeight != 1 ) {
rec.V2 = rec.V1 + blockHeight * atlas.invVerElementSize;
rec.V2 = rec.V1 + blockHeight * TerrainAtlas2D.invElementSize;
}
if( swapU ) rec.SwapU();

80
Utils/TerrainAtlas2D.cs Normal file
View file

@ -0,0 +1,80 @@
using System;
using System.Drawing;
using ClassicalSharp.GraphicsAPI;
namespace ClassicalSharp {
public static class TileSide {
public const int Left = 0;
public const int Right = 1;
public const int Front = 2;
public const int Back = 3;
public const int Bottom = 4;
public const int Top = 5;
}
public class TerrainAtlas2D : IDisposable {
public const int ElementsPerRow = 16, RowsCount = 16;
public const float invElementSize = 0.0625f;
public readonly int UsedRowsCount = 5;
public Bitmap AtlasBitmap;
public int elementSize;
public IGraphicsApi GraphicsApi;
public int TexId;
public void UpdateState( Bitmap bmp ) {
AtlasBitmap = bmp;
elementSize = bmp.Width >> 4;
using( FastBitmap fastBmp = new FastBitmap( bmp, true ) ) {
MakeOptimisedTexture( fastBmp );
TexId = GraphicsApi.LoadTexture( fastBmp );
}
}
public int LoadTextureElement( int index ) {
int x = index & 0x0F;
int y = index >> 4;
using( FastBitmap atlas = new FastBitmap( AtlasBitmap, true ) ) {
Bitmap bmp = new Bitmap( elementSize, elementSize );
using( FastBitmap dst = new FastBitmap( bmp, true ) ) {
Utils.MovePortion( x * elementSize, y * elementSize, 0, 0, atlas, dst, elementSize );
return GraphicsApi.LoadTexture( dst );
}
}
}
public TextureRectangle GetTexRec( int index ) {
int x = index & 0x0F;
int y = index >> 4;
return new TextureRectangle( x * invElementSize, y * invElementSize, invElementSize, invElementSize );
}
public void Dispose() {
if( AtlasBitmap != null ) {
AtlasBitmap.Dispose();
}
GraphicsApi.DeleteTexture( ref TexId );
}
static ushort[] rowFlags = { 0xFFFF, 0xFFEE, 0xFFE0, 0xFFE0, 0xFFFF, 0xFA00 };
void MakeOptimisedTexture( FastBitmap atlas ) {
int srcIndex = 0, destIndex = 0;
for( int y = 0; y < 6; y++ ) {
int flags = rowFlags[y];
for( int x = 0; x < ElementsPerRow; x++ ) {
bool isUsed = ( flags & 1 << ( 15 - x ) ) != 0;
if( isUsed && srcIndex != destIndex ) {
int dstX = ( destIndex & 0x0F ) * elementSize;
int dstY = ( destIndex >> 4 ) * elementSize;
Utils.MovePortion( x * elementSize, y * elementSize, dstX, dstY, atlas, atlas, elementSize );
}
srcIndex++;
if( isUsed ) destIndex++;
}
}
}
}
}

View file

@ -10,10 +10,10 @@ namespace ClassicalSharp {
internal int elementsPerBitmap;
public float invElementSize;
public TextureRectangle GetTexRec( int texId, out int index ) {
public TextureRectangle GetTexRec( int texId, int uCount, out int index ) {
index = texId / usedElementsPerAtlas1D;
int y = texId % usedElementsPerAtlas1D;
return new TextureRectangle( 0, y * invElementSize, 1, invElementSize );
return new TextureRectangle( 0, y * invElementSize, uCount, invElementSize );
}
public int Get1DIndex( int texId ) {
@ -24,34 +24,35 @@ namespace ClassicalSharp {
return texId % usedElementsPerAtlas1D;
}
public int[] CreateFrom2DAtlas( IGraphicsApi graphics, TextureAtlas2D atlas2D, int maxVerSize ) {
int verElements = maxVerSize / atlas2D.verElementSize;
int totalElements = atlas2D.UsedRowsCount * atlas2D.ElementsPerRow;
public int[] CreateFrom2DAtlas( IGraphicsApi graphics, TerrainAtlas2D atlas2D, int maxVerSize ) {
int verElements = maxVerSize / atlas2D.elementSize;
int totalElements = atlas2D.UsedRowsCount * TerrainAtlas2D.ElementsPerRow;
int elemSize = atlas2D.elementSize;
int atlasesCount = totalElements / verElements + ( totalElements % verElements != 0 ? 1 : 0 );
usedElementsPerAtlas1D = Math.Min( verElements, totalElements ); // in case verElements > totalElements
int atlas1DHeight = Utils.NextPowerOf2( usedElementsPerAtlas1D * atlas2D.verElementSize );
int atlas1DHeight = Utils.NextPowerOf2( usedElementsPerAtlas1D * atlas2D.elementSize );
int index = 0;
int x = 0, y = 0;
int[] texIds = new int[atlasesCount];
Utils.LogDebug( "Loaded new atlas: {0} bmps, {1} per bmp", atlasesCount, usedElementsPerAtlas1D );
using( FastBitmap atlas = new FastBitmap( atlas2D.AtlasBitmap, true ) ) {
for( int i = 0; i < texIds.Length; i++ ) {
Bitmap atlas1d = new Bitmap( atlas2D.horElementSize, atlas1DHeight );
using( FastBitmap dest = new FastBitmap( atlas1d, true ) ) {
for( int j = 0; j < usedElementsPerAtlas1D; j++ ) {
atlas2D.GetCoords( index, ref x, ref y );
atlas2D.CopyPortion( x, y, 0, j * atlas2D.verElementSize, atlas, dest );
Bitmap atlas1d = new Bitmap( atlas2D.elementSize, atlas1DHeight );
using( FastBitmap dst = new FastBitmap( atlas1d, true ) ) {
for( int y_1D = 0; y_1D < usedElementsPerAtlas1D; y_1D++ ) {
int x = index & 0x0F;
int y = index >> 4;
Utils.MovePortion( x * elemSize, y * elemSize, 0, y_1D * elemSize, atlas, dst, elemSize );
index++;
}
texIds[i] = graphics.LoadTexture( dest );
texIds[i] = graphics.LoadTexture( dst );
}
atlas1d.Dispose();
}
}
elementsPerBitmap = atlas1DHeight / atlas2D.verElementSize;
elementsPerBitmap = atlas1DHeight / atlas2D.elementSize;
invElementSize = 1f / elementsPerBitmap;
return texIds;
}

View file

@ -1,128 +0,0 @@
using System;
using System.Drawing;
using ClassicalSharp.GraphicsAPI;
namespace ClassicalSharp {
public struct TextureRectangle {
public float U1, V1, U2, V2;
public TextureRectangle( float u, float v, float uWidth, float vHeight ) {
U1 = u;
V1 = v;
U2 = u + uWidth;
V2 = v + vHeight;
}
public static TextureRectangle FromPoints( float u1, float u2, float v1, float v2 ) {
TextureRectangle rec;
rec.U1 = u1;
rec.U2 = u2;
rec.V1 = v1;
rec.V2 = v2;
return rec;
}
public override string ToString() {
return String.Format( "{0}, {1} : {2}, {3}", U1, V1, U2, V2 );
}
internal void SwapU() {
float u2 = U2;
U2 = U1;
U1 = u2;
}
}
public static class TileSide {
public const int Left = 0;
public const int Right = 1;
public const int Front = 2;
public const int Back = 3;
public const int Bottom = 4;
public const int Top = 5;
}
public class TextureAtlas2D : IDisposable {
public int ElementsPerRow;
public int RowsCount;
public int UsedRowsCount;
public Bitmap AtlasBitmap;
public int horElementSize, verElementSize;
public float invHorElementSize, invVerElementSize;
public IGraphicsApi GraphicsApi;
public TextureAtlas2D( IGraphicsApi graphics, string path, int elementsPerRow, int rows, int usedRows ) {
Bitmap bmp = new Bitmap( path );
GraphicsApi = graphics;
Init( bmp, elementsPerRow, rows, usedRows );
}
public TextureAtlas2D( IGraphicsApi graphics, Bitmap bmp, int elementsPerRow, int rows, int usedRows ) {
GraphicsApi = graphics;
Init( bmp, elementsPerRow, rows, usedRows );
}
void Init( Bitmap bmp, int elementsPerRow, int rows, int usedRows ) {
AtlasBitmap = bmp;
ElementsPerRow = elementsPerRow;
RowsCount = rows;
horElementSize = bmp.Width / ElementsPerRow;
verElementSize = bmp.Height / RowsCount;
UsedRowsCount = usedRows;
invHorElementSize = (float)horElementSize / bmp.Width;
invVerElementSize = (float)verElementSize / bmp.Height;
}
public int LoadTextureElement( int x, int y ) {
using( FastBitmap atlas = new FastBitmap( AtlasBitmap, true ) ) {
Bitmap bmp = new Bitmap( horElementSize, verElementSize );
using( FastBitmap dest = new FastBitmap( bmp, true ) ) {
CopyPortion( x, y, 0, 0, atlas, dest );
return GraphicsApi.LoadTexture( dest );
}
}
}
public int LoadTextureElement( int index ) {
int x = 0, y = 0;
GetCoords( index, ref x, ref y );
return LoadTextureElement( x, y );
}
public TextureRectangle GetTexRec( int x, int y ) {
return new TextureRectangle( x * invHorElementSize, y * invVerElementSize,
invHorElementSize, invVerElementSize );
}
public TextureRectangle GetTexRec( int index ) {
int x = 0, y = 0;
GetCoords( index, ref x, ref y );
return GetTexRec( x, y );
}
internal void GetCoords( int id, ref int x, ref int y ) {
x = id % ElementsPerRow;
y = id / ElementsPerRow;
}
internal unsafe void CopyPortion( int tileX, int tileY, int dstX, int dstY, FastBitmap atlas, FastBitmap dst ) {
int atlasX = tileX * horElementSize;
int atlasY = tileY * verElementSize;
for( int y = 0; y < verElementSize; y++ ) {
int* srcRow = atlas.GetRowPtr( atlasY + y );
int* dstRow = dst.GetRowPtr( dstY + y );
for( int x = 0; x < horElementSize; x++ ) {
dstRow[dstX + x] = srcRow[atlasX + x];
}
}
}
public void Dispose() {
if( AtlasBitmap != null ) {
AtlasBitmap.Dispose();
}
}
}
}

34
Utils/TextureRectangle.cs Normal file
View file

@ -0,0 +1,34 @@
using System;
namespace ClassicalSharp {
public struct TextureRectangle {
public float U1, V1, U2, V2;
public TextureRectangle( float u, float v, float uWidth, float vHeight ) {
U1 = u;
V1 = v;
U2 = u + uWidth;
V2 = v + vHeight;
}
public static TextureRectangle FromPoints( float u1, float u2, float v1, float v2 ) {
TextureRectangle rec;
rec.U1 = u1;
rec.U2 = u2;
rec.V1 = v1;
rec.V2 = v2;
return rec;
}
public override string ToString() {
return String.Format( "{0}, {1} : {2}, {3}", U1, V1, U2, V2 );
}
internal void SwapU() {
float u2 = U2;
U2 = U1;
U1 = u2;
}
}
}

View file

@ -1,9 +1,7 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Text;
using ClassicalSharp.GraphicsAPI;
using OpenTK;
using System;
using System.Drawing;
using System.Text;
using OpenTK;
namespace ClassicalSharp {
@ -230,118 +228,15 @@ namespace ClassicalSharp {
throw new NotSupportedException( "unsupported skin: " + bmp.Width + ", " + bmp.Height );
}
}
}
public struct Vector3I {
public static Vector3I Zero = new Vector3I( 0, 0, 0 );
public static Vector3I UnitX = new Vector3I( 1, 0, 0 );
public static Vector3I UnitY = new Vector3I( 0, 1, 0 );
public static Vector3I UnitZ = new Vector3I( 0, 0, 1 );
public int X, Y, Z;
public float Length {
get { return (float)Math.Sqrt( X * X + Y * Y + Z + Z ); }
}
public int LengthSquared {
get { return X * X + Y * Y + Z + Z; }
}
public Vector3 Normalise() {
float len = Length;
return new Vector3( X / len, Y / len, Z / len );
}
public Vector3I( int x, int y, int z ) {
X = x;
Y = y;
Z = z;
}
public Vector3I( int value ) {
X = value;
Y = value;
Z = value;
}
public static Vector3I operator + ( Vector3I left, Vector3I right ) {
return new Vector3I( left.X + right.X, left.Y + right.Y, left.Z + right.Z );
}
public static Vector3I operator - ( Vector3I left, Vector3I right ) {
return new Vector3I( left.X - right.X, left.Y - right.Y, left.Z - right.Z );
}
public static Vector3I operator - ( Vector3I left ) {
return new Vector3I( -left.X, -left.Y, -left.Z );
}
public static explicit operator Vector3I( Vector3 value ) {
return Truncate( value );
}
public static explicit operator Vector3( Vector3I value ) {
return new Vector3( value.X, value.Y, value.Z );
}
public override bool Equals( object obj ) {
return obj is Vector3I && Equals( (Vector3I)obj );
}
public bool Equals( Vector3I other ) {
return X == other.X && Y == other.Y && Z == other.Z;
}
public override int GetHashCode(){
int hashCode = 1000000007 * X;
hashCode += 1000000009 * Y;
hashCode += 1000000021 * Z;
return hashCode;
}
public static bool operator == ( Vector3I lhs, Vector3I rhs ) {
return lhs.X == rhs.X && lhs.Y == rhs.Y && lhs.Z == rhs.Z;
}
public static bool operator != (Vector3I lhs, Vector3I rhs) {
return !( lhs.X == rhs.X && lhs.Y == rhs.Y && lhs.Z == rhs.Z );
}
public static Vector3I Truncate( Vector3 vector ) {
int x = (int)vector.X;
int y = (int)vector.Y;
int z = (int)vector.Z;
return new Vector3I( x, y, z );
}
public static Vector3I Floor( Vector3 value ) {
return new Vector3I( Utils.Floor( value.X ), Utils.Floor( value.Y ), Utils.Floor( value.Z ) );
}
public static Vector3I Floor( float x, float y, float z ) {
return new Vector3I( Utils.Floor( x ), Utils.Floor( y ), Utils.Floor( z ) );
}
public static Vector3I Min( Vector3I p1, Vector3I p2 ) {
return new Vector3I( Math.Min( p1.X, p2.X ), Math.Min( p1.Y, p2.Y ), Math.Min( p1.Z, p2.Z ) );
}
public static Vector3I Min( int x1, int y1, int z1, int x2, int y2, int z2 ) {
return new Vector3I( Math.Min( x1, x2 ), Math.Min( y1, y2 ), Math.Min( z1, z2 ) );
}
public static Vector3I Max( Vector3I p1, Vector3I p2 ) {
return new Vector3I( Math.Max( p1.X, p2.X ), Math.Max( p1.Y, p2.Y ), Math.Max( p1.Z, p2.Z ) );
}
public static Vector3I Max( int x1, int y1, int z1, int x2, int y2, int z2 ) {
return new Vector3I( Math.Max( x1, x2 ), Math.Max( y1, y2 ), Math.Max( z1, z2 ) );
}
public override string ToString() {
return X + "," + Y + "," + Z;
internal unsafe static void MovePortion( int srcX, int srcY, int dstX, int dstY, FastBitmap src, FastBitmap dst, int size ) {
for( int y = 0; y < size; y++ ) {
int* srcRow = src.GetRowPtr( srcY + y );
int* dstRow = dst.GetRowPtr( dstY + y );
for( int x = 0; x < size; x++ ) {
dstRow[dstX + x] = srcRow[srcX + x];
}
}
}
}
}

118
Utils/Vector3I.cs Normal file
View file

@ -0,0 +1,118 @@
using System;
using OpenTK;
namespace ClassicalSharp {
public struct Vector3I {
public static Vector3I Zero = new Vector3I( 0, 0, 0 );
public static Vector3I UnitX = new Vector3I( 1, 0, 0 );
public static Vector3I UnitY = new Vector3I( 0, 1, 0 );
public static Vector3I UnitZ = new Vector3I( 0, 0, 1 );
public int X, Y, Z;
public float Length {
get { return (float)Math.Sqrt( X * X + Y * Y + Z + Z ); }
}
public int LengthSquared {
get { return X * X + Y * Y + Z + Z; }
}
public Vector3 Normalise() {
float len = Length;
return new Vector3( X / len, Y / len, Z / len );
}
public Vector3I( int x, int y, int z ) {
X = x;
Y = y;
Z = z;
}
public Vector3I( int value ) {
X = value;
Y = value;
Z = value;
}
public static Vector3I operator + ( Vector3I left, Vector3I right ) {
return new Vector3I( left.X + right.X, left.Y + right.Y, left.Z + right.Z );
}
public static Vector3I operator - ( Vector3I left, Vector3I right ) {
return new Vector3I( left.X - right.X, left.Y - right.Y, left.Z - right.Z );
}
public static Vector3I operator - ( Vector3I left ) {
return new Vector3I( -left.X, -left.Y, -left.Z );
}
public static explicit operator Vector3I( Vector3 value ) {
return Truncate( value );
}
public static explicit operator Vector3( Vector3I value ) {
return new Vector3( value.X, value.Y, value.Z );
}
public override bool Equals( object obj ) {
return obj is Vector3I && Equals( (Vector3I)obj );
}
public bool Equals( Vector3I other ) {
return X == other.X && Y == other.Y && Z == other.Z;
}
public override int GetHashCode(){
int hashCode = 1000000007 * X;
hashCode += 1000000009 * Y;
hashCode += 1000000021 * Z;
return hashCode;
}
public static bool operator == ( Vector3I lhs, Vector3I rhs ) {
return lhs.X == rhs.X && lhs.Y == rhs.Y && lhs.Z == rhs.Z;
}
public static bool operator != (Vector3I lhs, Vector3I rhs) {
return !( lhs.X == rhs.X && lhs.Y == rhs.Y && lhs.Z == rhs.Z );
}
public static Vector3I Truncate( Vector3 vector ) {
int x = (int)vector.X;
int y = (int)vector.Y;
int z = (int)vector.Z;
return new Vector3I( x, y, z );
}
public static Vector3I Floor( Vector3 value ) {
return new Vector3I( Utils.Floor( value.X ), Utils.Floor( value.Y ), Utils.Floor( value.Z ) );
}
public static Vector3I Floor( float x, float y, float z ) {
return new Vector3I( Utils.Floor( x ), Utils.Floor( y ), Utils.Floor( z ) );
}
public static Vector3I Min( Vector3I p1, Vector3I p2 ) {
return new Vector3I( Math.Min( p1.X, p2.X ), Math.Min( p1.Y, p2.Y ), Math.Min( p1.Z, p2.Z ) );
}
public static Vector3I Min( int x1, int y1, int z1, int x2, int y2, int z2 ) {
return new Vector3I( Math.Min( x1, x2 ), Math.Min( y1, y2 ), Math.Min( z1, z2 ) );
}
public static Vector3I Max( Vector3I p1, Vector3I p2 ) {
return new Vector3I( Math.Max( p1.X, p2.X ), Math.Max( p1.Y, p2.Y ), Math.Max( p1.Z, p2.Z ) );
}
public static Vector3I Max( int x1, int y1, int z1, int x2, int y2, int z2 ) {
return new Vector3I( Math.Max( x1, x2 ), Math.Max( y1, y2 ), Math.Max( z1, z2 ) );
}
public override string ToString() {
return X + "," + Y + "," + Z;
}
}
}