Adding initial files
This commit is contained in:
240
axios/DrawingSystem/AssetCreator.cs
Normal file
240
axios/DrawingSystem/AssetCreator.cs
Normal file
@@ -0,0 +1,240 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using FarseerPhysics.Collision;
|
||||
using FarseerPhysics.Collision.Shapes;
|
||||
using FarseerPhysics.Common;
|
||||
using FarseerPhysics.Common.Decomposition;
|
||||
using FarseerPhysics.Dynamics;
|
||||
using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Content;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
|
||||
namespace FarseerPhysics.SamplesFramework
|
||||
{
|
||||
public enum MaterialType
|
||||
{
|
||||
Blank,
|
||||
Dots,
|
||||
Squares,
|
||||
Waves,
|
||||
Pavement
|
||||
}
|
||||
|
||||
public class AssetCreator
|
||||
{
|
||||
private const int CircleSegments = 32;
|
||||
|
||||
private GraphicsDevice _device;
|
||||
private BasicEffect _effect;
|
||||
private Dictionary<MaterialType, Texture2D> _materials = new Dictionary<MaterialType, Texture2D>();
|
||||
|
||||
public AssetCreator(GraphicsDevice device)
|
||||
{
|
||||
_device = device;
|
||||
_effect = new BasicEffect(_device);
|
||||
}
|
||||
|
||||
public static Vector2 CalculateOrigin(Body b)
|
||||
{
|
||||
Vector2 lBound = new Vector2(float.MaxValue);
|
||||
AABB bounds;
|
||||
Transform trans;
|
||||
b.GetTransform(out trans);
|
||||
|
||||
for (int i = 0; i < b.FixtureList.Count; ++i)
|
||||
{
|
||||
for (int j = 0; j < b.FixtureList[i].Shape.ChildCount; ++j)
|
||||
{
|
||||
b.FixtureList[i].Shape.ComputeAABB(out bounds, ref trans, j);
|
||||
Vector2.Min(ref lBound, ref bounds.LowerBound, out lBound);
|
||||
}
|
||||
}
|
||||
// calculate body offset from its center and add a 1 pixel border
|
||||
// because we generate the textures a little bigger than the actual body's fixtures
|
||||
return ConvertUnits.ToDisplayUnits(b.Position - lBound) + new Vector2(1f);
|
||||
}
|
||||
|
||||
public void LoadContent(ContentManager contentManager)
|
||||
{
|
||||
_materials[MaterialType.Blank] = contentManager.Load<Texture2D>("Materials/blank");
|
||||
_materials[MaterialType.Dots] = contentManager.Load<Texture2D>("Materials/dots");
|
||||
_materials[MaterialType.Squares] = contentManager.Load<Texture2D>("Materials/squares");
|
||||
_materials[MaterialType.Waves] = contentManager.Load<Texture2D>("Materials/waves");
|
||||
_materials[MaterialType.Pavement] = contentManager.Load<Texture2D>("Materials/pavement");
|
||||
}
|
||||
|
||||
public Texture2D TextureFromShape(Shape shape, MaterialType type, Color color, float materialScale)
|
||||
{
|
||||
switch (shape.ShapeType)
|
||||
{
|
||||
case ShapeType.Circle:
|
||||
return CircleTexture(shape.Radius, type, color, materialScale);
|
||||
case ShapeType.Polygon:
|
||||
return TextureFromVertices(((PolygonShape) shape).Vertices, type, color, materialScale);
|
||||
default:
|
||||
throw new NotSupportedException("The specified shape type is not supported.");
|
||||
}
|
||||
}
|
||||
|
||||
public Texture2D TextureFromVertices(Vertices vertices, MaterialType type, Color color, float materialScale)
|
||||
{
|
||||
// copy vertices
|
||||
Vertices verts = new Vertices(vertices);
|
||||
|
||||
// scale to display units (i.e. pixels) for rendering to texture
|
||||
Vector2 scale = ConvertUnits.ToDisplayUnits(Vector2.One);
|
||||
verts.Scale(ref scale);
|
||||
|
||||
// translate the boundingbox center to the texture center
|
||||
// because we use an orthographic projection for rendering later
|
||||
AABB vertsBounds = verts.GetCollisionBox();
|
||||
verts.Translate(-vertsBounds.Center);
|
||||
|
||||
List<Vertices> decomposedVerts;
|
||||
if (!verts.IsConvex())
|
||||
{
|
||||
decomposedVerts = EarclipDecomposer.ConvexPartition(verts);
|
||||
}
|
||||
else
|
||||
{
|
||||
decomposedVerts = new List<Vertices>();
|
||||
decomposedVerts.Add(verts);
|
||||
}
|
||||
List<VertexPositionColorTexture[]> verticesFill =
|
||||
new List<VertexPositionColorTexture[]>(decomposedVerts.Count);
|
||||
|
||||
materialScale /= _materials[type].Width;
|
||||
|
||||
for (int i = 0; i < decomposedVerts.Count; ++i)
|
||||
{
|
||||
verticesFill.Add(new VertexPositionColorTexture[3 * (decomposedVerts[i].Count - 2)]);
|
||||
for (int j = 0; j < decomposedVerts[i].Count - 2; ++j)
|
||||
{
|
||||
// fill vertices
|
||||
verticesFill[i][3 * j].Position = new Vector3(decomposedVerts[i][0], 0f);
|
||||
verticesFill[i][3 * j + 1].Position = new Vector3(decomposedVerts[i].NextVertex(j), 0f);
|
||||
verticesFill[i][3 * j + 2].Position = new Vector3(decomposedVerts[i].NextVertex(j + 1), 0f);
|
||||
verticesFill[i][3 * j].TextureCoordinate = decomposedVerts[i][0] * materialScale;
|
||||
verticesFill[i][3 * j + 1].TextureCoordinate = decomposedVerts[i].NextVertex(j) * materialScale;
|
||||
verticesFill[i][3 * j + 2].TextureCoordinate = decomposedVerts[i].NextVertex(j + 1) * materialScale;
|
||||
verticesFill[i][3 * j].Color =
|
||||
verticesFill[i][3 * j + 1].Color = verticesFill[i][3 * j + 2].Color = color;
|
||||
}
|
||||
}
|
||||
|
||||
// calculate outline
|
||||
VertexPositionColor[] verticesOutline = new VertexPositionColor[2 * verts.Count];
|
||||
for (int i = 0; i < verts.Count; ++i)
|
||||
{
|
||||
verticesOutline[2 * i].Position = new Vector3(verts[i], 0f);
|
||||
verticesOutline[2 * i + 1].Position = new Vector3(verts.NextVertex(i), 0f);
|
||||
verticesOutline[2 * i].Color = verticesOutline[2 * i + 1].Color = Color.Black;
|
||||
}
|
||||
|
||||
Vector2 vertsSize = new Vector2(vertsBounds.UpperBound.X - vertsBounds.LowerBound.X,
|
||||
vertsBounds.UpperBound.Y - vertsBounds.LowerBound.Y);
|
||||
return RenderTexture((int)vertsSize.X, (int)vertsSize.Y,
|
||||
_materials[type], verticesFill, verticesOutline);
|
||||
}
|
||||
|
||||
public Texture2D CircleTexture(float radius, MaterialType type, Color color, float materialScale)
|
||||
{
|
||||
return EllipseTexture(radius, radius, type, color, materialScale);
|
||||
}
|
||||
|
||||
public Texture2D EllipseTexture(float radiusX, float radiusY, MaterialType type, Color color,
|
||||
float materialScale)
|
||||
{
|
||||
VertexPositionColorTexture[] verticesFill = new VertexPositionColorTexture[3 * (CircleSegments - 2)];
|
||||
VertexPositionColor[] verticesOutline = new VertexPositionColor[2 * CircleSegments];
|
||||
const float segmentSize = MathHelper.TwoPi / CircleSegments;
|
||||
float theta = segmentSize;
|
||||
|
||||
radiusX = ConvertUnits.ToDisplayUnits(radiusX);
|
||||
radiusY = ConvertUnits.ToDisplayUnits(radiusY);
|
||||
materialScale /= _materials[type].Width;
|
||||
|
||||
Vector2 start = new Vector2(radiusX, 0f);
|
||||
|
||||
for (int i = 0; i < CircleSegments - 2; ++i)
|
||||
{
|
||||
Vector2 p1 = new Vector2(radiusX * (float)Math.Cos(theta), radiusY * (float)Math.Sin(theta));
|
||||
Vector2 p2 = new Vector2(radiusX * (float)Math.Cos(theta + segmentSize),
|
||||
radiusY * (float)Math.Sin(theta + segmentSize));
|
||||
// fill vertices
|
||||
verticesFill[3 * i].Position = new Vector3(start, 0f);
|
||||
verticesFill[3 * i + 1].Position = new Vector3(p1, 0f);
|
||||
verticesFill[3 * i + 2].Position = new Vector3(p2, 0f);
|
||||
verticesFill[3 * i].TextureCoordinate = start * materialScale;
|
||||
verticesFill[3 * i + 1].TextureCoordinate = p1 * materialScale;
|
||||
verticesFill[3 * i + 2].TextureCoordinate = p2 * materialScale;
|
||||
verticesFill[3 * i].Color = verticesFill[3 * i + 1].Color = verticesFill[3 * i + 2].Color = color;
|
||||
|
||||
// outline vertices
|
||||
if (i == 0)
|
||||
{
|
||||
verticesOutline[0].Position = new Vector3(start, 0f);
|
||||
verticesOutline[1].Position = new Vector3(p1, 0f);
|
||||
verticesOutline[0].Color = verticesOutline[1].Color = Color.Black;
|
||||
}
|
||||
if (i == CircleSegments - 3)
|
||||
{
|
||||
verticesOutline[2 * CircleSegments - 2].Position = new Vector3(p2, 0f);
|
||||
verticesOutline[2 * CircleSegments - 1].Position = new Vector3(start, 0f);
|
||||
verticesOutline[2 * CircleSegments - 2].Color =
|
||||
verticesOutline[2 * CircleSegments - 1].Color = Color.Black;
|
||||
}
|
||||
verticesOutline[2 * i + 2].Position = new Vector3(p1, 0f);
|
||||
verticesOutline[2 * i + 3].Position = new Vector3(p2, 0f);
|
||||
verticesOutline[2 * i + 2].Color = verticesOutline[2 * i + 3].Color = Color.Black;
|
||||
|
||||
theta += segmentSize;
|
||||
}
|
||||
|
||||
return RenderTexture((int)(radiusX * 2f), (int)(radiusY * 2f),
|
||||
_materials[type], verticesFill, verticesOutline);
|
||||
}
|
||||
|
||||
private Texture2D RenderTexture(int width, int height, Texture2D material,
|
||||
VertexPositionColorTexture[] verticesFill,
|
||||
VertexPositionColor[] verticesOutline)
|
||||
{
|
||||
List<VertexPositionColorTexture[]> fill = new List<VertexPositionColorTexture[]>(1);
|
||||
fill.Add(verticesFill);
|
||||
return RenderTexture(width, height, material, fill, verticesOutline);
|
||||
}
|
||||
|
||||
private Texture2D RenderTexture(int width, int height, Texture2D material,
|
||||
List<VertexPositionColorTexture[]> verticesFill,
|
||||
VertexPositionColor[] verticesOutline)
|
||||
{
|
||||
Matrix halfPixelOffset = Matrix.CreateTranslation(-0.5f, -0.5f, 0f);
|
||||
PresentationParameters pp = _device.PresentationParameters;
|
||||
RenderTarget2D texture = new RenderTarget2D(_device, width + 2, height + 2, false, SurfaceFormat.Color,
|
||||
DepthFormat.None, pp.MultiSampleCount,
|
||||
RenderTargetUsage.DiscardContents);
|
||||
_device.RasterizerState = RasterizerState.CullNone;
|
||||
_device.SamplerStates[0] = SamplerState.LinearWrap;
|
||||
|
||||
_device.SetRenderTarget(texture);
|
||||
_device.Clear(Color.Transparent);
|
||||
_effect.Projection = Matrix.CreateOrthographic(width + 2f, -height - 2f, 0f, 1f);
|
||||
_effect.View = halfPixelOffset;
|
||||
// render shape;
|
||||
_effect.TextureEnabled = true;
|
||||
_effect.Texture = material;
|
||||
_effect.VertexColorEnabled = true;
|
||||
_effect.Techniques[0].Passes[0].Apply();
|
||||
for (int i = 0; i < verticesFill.Count; ++i)
|
||||
{
|
||||
_device.DrawUserPrimitives(PrimitiveType.TriangleList, verticesFill[i], 0, verticesFill[i].Length / 3);
|
||||
}
|
||||
// render outline;
|
||||
_effect.TextureEnabled = false;
|
||||
_effect.Techniques[0].Passes[0].Apply();
|
||||
_device.DrawUserPrimitives(PrimitiveType.LineList, verticesOutline, 0, verticesOutline.Length / 2);
|
||||
_device.SetRenderTarget(null);
|
||||
return texture;
|
||||
}
|
||||
}
|
||||
}
|
183
axios/DrawingSystem/LineBatch.cs
Normal file
183
axios/DrawingSystem/LineBatch.cs
Normal file
@@ -0,0 +1,183 @@
|
||||
using System;
|
||||
using FarseerPhysics.Collision.Shapes;
|
||||
using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
|
||||
namespace FarseerPhysics.SamplesFramework
|
||||
{
|
||||
public class LineBatch : IDisposable
|
||||
{
|
||||
private const int DefaultBufferSize = 500;
|
||||
|
||||
// a basic effect, which contains the shaders that we will use to draw our
|
||||
// primitives.
|
||||
private BasicEffect _basicEffect;
|
||||
|
||||
// the device that we will issue draw calls to.
|
||||
private GraphicsDevice _device;
|
||||
|
||||
// hasBegun is flipped to true once Begin is called, and is used to make
|
||||
// sure users don't call End before Begin is called.
|
||||
private bool _hasBegun;
|
||||
|
||||
private bool _isDisposed;
|
||||
private VertexPositionColor[] _lineVertices;
|
||||
private int _lineVertsCount;
|
||||
|
||||
public LineBatch(GraphicsDevice graphicsDevice)
|
||||
: this(graphicsDevice, DefaultBufferSize)
|
||||
{
|
||||
}
|
||||
|
||||
public LineBatch(GraphicsDevice graphicsDevice, int bufferSize)
|
||||
{
|
||||
if (graphicsDevice == null)
|
||||
{
|
||||
throw new ArgumentNullException("graphicsDevice");
|
||||
}
|
||||
_device = graphicsDevice;
|
||||
|
||||
_lineVertices = new VertexPositionColor[bufferSize - bufferSize % 2];
|
||||
|
||||
// set up a new basic effect, and enable vertex colors.
|
||||
_basicEffect = new BasicEffect(graphicsDevice);
|
||||
_basicEffect.VertexColorEnabled = true;
|
||||
}
|
||||
|
||||
#region IDisposable Members
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
Dispose(true);
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
protected virtual void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing && !_isDisposed)
|
||||
{
|
||||
if (_basicEffect != null)
|
||||
_basicEffect.Dispose();
|
||||
|
||||
_isDisposed = true;
|
||||
}
|
||||
}
|
||||
|
||||
public void Begin(Matrix projection, Matrix view)
|
||||
{
|
||||
if (_hasBegun)
|
||||
{
|
||||
throw new InvalidOperationException("End must be called before Begin can be called again.");
|
||||
}
|
||||
|
||||
_device.SamplerStates[0] = SamplerState.AnisotropicClamp;
|
||||
//tell our basic effect to begin.
|
||||
_basicEffect.Projection = projection;
|
||||
_basicEffect.View = view;
|
||||
_basicEffect.CurrentTechnique.Passes[0].Apply();
|
||||
|
||||
// flip the error checking boolean. It's now ok to call DrawLineShape, Flush,
|
||||
// and End.
|
||||
_hasBegun = true;
|
||||
}
|
||||
|
||||
public void DrawLineShape(Shape shape)
|
||||
{
|
||||
DrawLineShape(shape, Color.Black);
|
||||
}
|
||||
|
||||
public void DrawLineShape(Shape shape, Color color)
|
||||
{
|
||||
if (!_hasBegun)
|
||||
{
|
||||
throw new InvalidOperationException("Begin must be called before DrawLineShape can be called.");
|
||||
}
|
||||
if (shape.ShapeType != ShapeType.Edge &&
|
||||
shape.ShapeType != ShapeType.Loop)
|
||||
{
|
||||
throw new NotSupportedException("The specified shapeType is not supported by LineBatch.");
|
||||
}
|
||||
if (shape.ShapeType == ShapeType.Edge)
|
||||
{
|
||||
if (_lineVertsCount >= _lineVertices.Length)
|
||||
{
|
||||
Flush();
|
||||
}
|
||||
EdgeShape edge = (EdgeShape)shape;
|
||||
_lineVertices[_lineVertsCount].Position = new Vector3(edge.Vertex1, 0f);
|
||||
_lineVertices[_lineVertsCount + 1].Position = new Vector3(edge.Vertex2, 0f);
|
||||
_lineVertices[_lineVertsCount].Color = _lineVertices[_lineVertsCount + 1].Color = color;
|
||||
_lineVertsCount += 2;
|
||||
}
|
||||
else if (shape.ShapeType == ShapeType.Loop)
|
||||
{
|
||||
LoopShape loop = (LoopShape)shape;
|
||||
for (int i = 0; i < loop.Vertices.Count; ++i)
|
||||
{
|
||||
if (_lineVertsCount >= _lineVertices.Length)
|
||||
{
|
||||
Flush();
|
||||
}
|
||||
_lineVertices[_lineVertsCount].Position = new Vector3(loop.Vertices[i], 0f);
|
||||
_lineVertices[_lineVertsCount + 1].Position = new Vector3(loop.Vertices.NextVertex(i), 0f);
|
||||
_lineVertices[_lineVertsCount].Color = _lineVertices[_lineVertsCount + 1].Color = color;
|
||||
_lineVertsCount += 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void DrawLine(Vector2 v1, Vector2 v2)
|
||||
{
|
||||
DrawLine(v1, v2, Color.Black);
|
||||
}
|
||||
|
||||
public void DrawLine(Vector2 v1, Vector2 v2, Color color)
|
||||
{
|
||||
if (!_hasBegun)
|
||||
{
|
||||
throw new InvalidOperationException("Begin must be called before DrawLineShape can be called.");
|
||||
}
|
||||
if (_lineVertsCount >= _lineVertices.Length)
|
||||
{
|
||||
Flush();
|
||||
}
|
||||
_lineVertices[_lineVertsCount].Position = new Vector3(v1, 0f);
|
||||
_lineVertices[_lineVertsCount + 1].Position = new Vector3(v2, 0f);
|
||||
_lineVertices[_lineVertsCount].Color = _lineVertices[_lineVertsCount + 1].Color = color;
|
||||
_lineVertsCount += 2;
|
||||
}
|
||||
|
||||
// End is called once all the primitives have been drawn using AddVertex.
|
||||
// it will call Flush to actually submit the draw call to the graphics card, and
|
||||
// then tell the basic effect to end.
|
||||
public void End()
|
||||
{
|
||||
if (!_hasBegun)
|
||||
{
|
||||
throw new InvalidOperationException("Begin must be called before End can be called.");
|
||||
}
|
||||
|
||||
// Draw whatever the user wanted us to draw
|
||||
Flush();
|
||||
|
||||
_hasBegun = false;
|
||||
}
|
||||
|
||||
private void Flush()
|
||||
{
|
||||
if (!_hasBegun)
|
||||
{
|
||||
throw new InvalidOperationException("Begin must be called before Flush can be called.");
|
||||
}
|
||||
if (_lineVertsCount >= 2)
|
||||
{
|
||||
int primitiveCount = _lineVertsCount / 2;
|
||||
// submit the draw call to the graphics card
|
||||
_device.DrawUserPrimitives(PrimitiveType.LineList, _lineVertices, 0, primitiveCount);
|
||||
_lineVertsCount -= primitiveCount * 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
23
axios/DrawingSystem/Sprite.cs
Normal file
23
axios/DrawingSystem/Sprite.cs
Normal file
@@ -0,0 +1,23 @@
|
||||
using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
|
||||
namespace FarseerPhysics.SamplesFramework
|
||||
{
|
||||
public struct Sprite
|
||||
{
|
||||
public Vector2 Origin;
|
||||
public Texture2D Texture;
|
||||
|
||||
public Sprite(Texture2D texture, Vector2 origin)
|
||||
{
|
||||
this.Texture = texture;
|
||||
this.Origin = origin;
|
||||
}
|
||||
|
||||
public Sprite(Texture2D sprite)
|
||||
{
|
||||
Texture = sprite;
|
||||
Origin = new Vector2(sprite.Width / 2f, sprite.Height / 2f);
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user