public DrawableModel(KModel model, Texture2D texture, GraphicsDevice graphicsDevice) { _graphicsDevice = graphicsDevice; _texture = texture; // Create vertex buffer var vertexArray = ModelRendering.ToNonIndexed(model, texture); _buffer = new VertexBuffer(graphicsDevice, VertexPositionTexture.VertexDeclaration, vertexArray.Length, BufferUsage.WriteOnly); _buffer.SetData(vertexArray); }
public void Append(KModel other) { var vertexCount = Vertices.Count; Vertices.AddRange(other.Vertices.Select(v => v.Clone())); foreach (var facet in other.Facets) { var newFacet = facet.Clone(); newFacet.Ve0 += vertexCount; newFacet.Ve1 += vertexCount; newFacet.Ve2 += vertexCount; Facets.Add(newFacet); } }
public static VertexPositionTexture[] ToNonIndexed(KModel model, Texture2D texture) { var result = new VertexPositionTexture[3 * model.Facets.Count]; var arrayIndex = 0; for (int facetIndex = 0; facetIndex < model.Facets.Count; facetIndex++) { var facet = model.Facets[facetIndex]; result[arrayIndex].Position = model.Vertices[facet.Ve0].Pt; result[arrayIndex].TextureCoordinate = facet.Tex0; arrayIndex++; result[arrayIndex].Position = model.Vertices[facet.Ve1].Pt; result[arrayIndex].TextureCoordinate = facet.Tex1; arrayIndex++; result[arrayIndex].Position = model.Vertices[facet.Ve2].Pt; result[arrayIndex].TextureCoordinate = facet.Tex2; arrayIndex++; } // If texture coordinates are in pixels, then scale them all to [0,1] x [0,1] if (model.TexCoordsAreInPixels) { var scaleX = 1f / texture.Bounds.Width; var scaleY = 1f / texture.Bounds.Height; var bounds = texture.Bounds; for (int i = 0; i < result.Length; i++) { result[i].TextureCoordinate.X *= scaleX; result[i].TextureCoordinate.Y *= scaleY; } } return result; }
private static void SplitEachFacetInFour(KModel model) { // Create a new vertex at the midpoint of every edge var edge2Vertex = new Dictionary<Tuple<int, int>, int>(); foreach (var facet in model.Facets) { foreach (var t in new Tuple<int, int>[] { Tuple.Create(facet.Ve0, facet.Ve1), Tuple.Create(facet.Ve1, facet.Ve2), Tuple.Create(facet.Ve2, facet.Ve0)}) { if (!edge2Vertex.ContainsKey(t)) { Vector3 midPoint = (model.Vertices[t.Item1].Pt + model.Vertices[t.Item2].Pt) / 2; int veMidpoint = model.AddVertex(midPoint); edge2Vertex.Add(t, veMidpoint); edge2Vertex.Add(Tuple.Create(t.Item2, t.Item1), veMidpoint); } } } // Split each facet in four var originalFacetCount = model.Facets.Count; for (int faId = 0; faId < originalFacetCount; faId++) { var f = model.Facets[faId]; // Corners of original facet int ve0 = f.Ve0; int ve1 = f.Ve1; int ve2 = f.Ve2; // Edge midpoints int ve01 = edge2Vertex[Tuple.Create(f.Ve0, f.Ve1)]; int ve12 = edge2Vertex[Tuple.Create(f.Ve1, f.Ve2)]; int ve20 = edge2Vertex[Tuple.Create(f.Ve2, f.Ve0)]; // Texture coordinates of corners var tex0 = f.Tex0; var tex1 = f.Tex1; var tex2 = f.Tex2; // Texture coordinates of midpoints var tex01 = 0.5f * (tex0 + tex1); var tex12 = 0.5f * (tex1 + tex2); var tex20 = 0.5f * (tex2 + tex0); // // 2 // / \ // 20---12 // / \ / \ // 0---01--1 // First facet: 0-01-20 (change the original) f.Ve1 = ve01; f.Ve2 = ve20; f.Tex1 = tex01; f.Tex2 = tex20; // 01-1-12 f = model.Facets[model.AddFacet(ve01, ve1, ve12)]; f.Tex0 = tex01; f.Tex1 = tex1; f.Tex2 = tex12; // 01-12-20 f = model.Facets[model.AddFacet(ve01, ve12, ve20)]; f.Tex0 = tex01; f.Tex1 = tex12; f.Tex2 = tex20; // 20-12-2 f = model.Facets[model.AddFacet(ve20, ve12, ve2)]; f.Tex0 = tex20; f.Tex1 = tex12; f.Tex2 = tex2; } }
/// <summary> /// Creates an icosahedron (regular polyhedron with 20 triangle sides) with vertices on the unit sphere. /// </summary> public static KModel CreateIcosahedron(Rectangle texRect) { // aka golden ratio float tao = (float)(1 + Math.Sqrt(5)) / 2; var model = new KModel(); int v0 = model.AddVertex(new Vector3(1, tao, 0).Normalized()); int v1 = model.AddVertex(new Vector3(-1, tao, 0).Normalized()); int v2 = model.AddVertex(new Vector3(1, -tao, 0).Normalized()); int v3 = model.AddVertex(new Vector3(-1, -tao, 0).Normalized()); int v4 = model.AddVertex(new Vector3(0, 1, tao).Normalized()); int v5 = model.AddVertex(new Vector3(0, -1, tao).Normalized()); int v6 = model.AddVertex(new Vector3(0, 1, -tao).Normalized()); int v7 = model.AddVertex(new Vector3(0, -1, -tao).Normalized()); int v8 = model.AddVertex(new Vector3(tao, 0, 1).Normalized()); int v9 = model.AddVertex(new Vector3(-tao, 0, 1).Normalized()); int vA = model.AddVertex(new Vector3(tao, 0, -1).Normalized()); int vB = model.AddVertex(new Vector3(-tao, 0, -1).Normalized()); model.AddFacet(v0, v6, v1); model.AddFacet(v0, vA, v6); model.AddFacet(v0, v8, vA); model.AddFacet(v0, v4, v8); model.AddFacet(v0, v1, v4); model.AddFacet(v3, v5, v9); model.AddFacet(v3, v2, v5); model.AddFacet(v3, v7, v2); model.AddFacet(v3, vB, v7); model.AddFacet(v3, v9, vB); model.AddFacet(v1, v6, vB); model.AddFacet(v1, v9, v4); model.AddFacet(v1, vB, v9); model.AddFacet(v2, v7, vA); model.AddFacet(v2, v8, v5); model.AddFacet(v2, vA, v8); model.AddFacet(v4, v5, v8); model.AddFacet(v4, v9, v5); model.AddFacet(v6, v7, vB); model.AddFacet(v6, vA, v7); // Set texture coordinates on all facets foreach (var facet in model.Facets) { facet.Tex0 = new Vector2(texRect.Left, texRect.Top); facet.Tex1 = new Vector2((texRect.Left + texRect.Right) / 2f, texRect.Bottom); facet.Tex2 = new Vector2(texRect.Right, texRect.Top); } return model; }
/// <summary> /// LoadContent will be called once per game and is the place to load /// all of your content. /// </summary> protected override void LoadContent() { // Create a new SpriteBatch, which can be used to draw textures. spriteBatch = new SpriteBatch(GraphicsDevice); // TODO: use this.Content to load your game content here imageKK = Content.Load<Texture2D>(@"Images\KK"); imageBox = Content.Load<Texture2D>(@"Images\BoxSides"); imageBall = Content.Load<Texture2D>(@"Images\football"); imageSpikyBall = Content.Load<Texture2D>(@"Images\spiky"); var model = new KModel(); model.TexCoordsAreInPixels = false; for (int i = 3; i < 100; i = i+2) { var z = -i / 2; model.AddQuad( model.AddVertex(new Vector3(-i, -i, z)), model.AddVertex(new Vector3(i, -i, z)), model.AddVertex(new Vector3(-i, i, z)), model.AddVertex(new Vector3(i, i, z)), new Rectangle(0, 0, 1, 1)); } _drawableKK = new DrawableModel(model, imageKK, GraphicsDevice, false); model = new KModel(); model.AddBox(new BoundingBox(new Vector3(-5, 3, 1), new Vector3(-3, 5, 3)), new Rectangle(0, 64, 64, 64), true); model.AddBox(new BoundingBox(new Vector3(3, 3, 1), new Vector3(5, 5, 3)), new Rectangle(0, 0, 64, 64), true); model.AddBox(new BoundingBox(new Vector3(-5, -5, 1), new Vector3(-3, -3, 3)), new Rectangle(0, 0, 64, 64), true); for (int i = 0; i < 11; i++) for (int j = 0; j < 11; j++) if (i % 2 == 0 || j % 2 == 0) { model.AddBox(new BoundingBox(new Vector3(3 + 2*i, -5 - 2*j, 1), new Vector3(5 + 2*i, -3 - 2*j, 3)), new Rectangle(0, 128, 225, 225), false); } _drawableBox = new DrawableModel(model, imageBox, GraphicsDevice, false); model = GeometricalPrimitives.CreateBall(2, new Rectangle(0, 0, 1, 1)); model.TexCoordsAreInPixels = false; _drawableBall = new DrawableModel(model, imageBall, GraphicsDevice, true); model = GeometricalPrimitives.CreateSpikyBall(3, 0.2f, new Rectangle(0, 0, 1, 1)); model.TexCoordsAreInPixels = false; _drawableSpikyBall = new DrawableModel(model, imageSpikyBall, GraphicsDevice, true); // Matrix test var mat = Matrix.CreateTranslation(1, 2, 3); Console.WriteLine(mat); }
/// <summary> /// LoadContent will be called once per game and is the place to load /// all of your content. /// </summary> protected override void LoadContent() { // Create a new SpriteBatch, which can be used to draw textures. spriteBatch = new SpriteBatch(GraphicsDevice); // TODO: use this.Content to load your game content here imageKK = Content.Load<Texture2D>(@"Images\KK"); imageBox = Content.Load<Texture2D>(@"Images\BoxSides"); imageBall = Content.Load<Texture2D>(@"Images\football"); var model = new KModel(); model.TexCoordsAreInPixels = false; for (int i = 3; i < 100; i = i+2) { var z = -i / 2; model.AddQuad( model.AddVertex(new Vector3(-i, -i, z)), model.AddVertex(new Vector3(i, -i, z)), model.AddVertex(new Vector3(-i, i, z)), model.AddVertex(new Vector3(i, i, z)), new Rectangle(0, 0, 1, 1)); } _drawableKK = new DrawableModel(model, imageKK, GraphicsDevice); model = new KModel(); model.AddBox(new BoundingBox(new Vector3(-5, -5, 1), new Vector3(-3, -3, 3)), new Rectangle(0, 0, 64, 64)); model.AddBox(new BoundingBox(new Vector3(-5, 3, 1), new Vector3(-3, 5, 3)), new Rectangle(0, 64, 64, 64)); model.AddBox(new BoundingBox(new Vector3(3, -5, 1), new Vector3(5, -3, 3)), new Rectangle(0, 64, 64, 64)); model.AddBox(new BoundingBox(new Vector3(3, 3, 1), new Vector3(5, 5, 3)), new Rectangle(0, 0, 64, 64)); _drawableBox = new DrawableModel(model, imageBox, GraphicsDevice); model = GeometricalPrimitives.CreateBall(2, new Rectangle(0, 0, 1, 1)); model.TexCoordsAreInPixels = false; /* model.Transform(Matrix.CreateTranslation(1, 0, 0)); var model2 = GeometricalPrimitives.CreateBall(3, new Rectangle(0, 0, 1, 1)); model2.Transform(Matrix.CreateScale(0.5f)); model2.Transform(Matrix.CreateTranslation(-1, 0, 0)); model.Append(model2);*/ _drawableBall = new DrawableModel(model, imageBall, GraphicsDevice); // Matrix test var mat = Matrix.CreateTranslation(1, 2, 3); Console.WriteLine(mat); }
/// <summary> /// LoadContent will be called once per game and is the place to load /// all of your content. /// </summary> protected override void LoadContent() { // Create a new SpriteBatch, which can be used to draw textures. _spriteBatch = new SpriteBatch(GraphicsDevice); _font = Content.Load<SpriteFont>(@"Fonts\TestFont"); // TODO: use this.Content to load your game content here _imageKK = Content.Load<Texture2D>(@"Images\KK"); var imageFloor = Content.Load<Texture2D>(@"Images\FloorWoodLight"); var imageBox = Content.Load<Texture2D>(@"Images\BoxSides"); var imageBall = Content.Load<Texture2D>(@"Images\football"); var imageSpikyBall = Content.Load<Texture2D>(@"Images\spiky"); _levelSearch = new Search3DSimple<FacetRef>(); var model = new KModel(); model.TexCoordsAreInPixels = false; int size = 100; model.AddQuad( model.AddVertex(new Vector3(-size, -size, 0)), model.AddVertex(new Vector3(size, -size, 0)), model.AddVertex(new Vector3(-size, size, 0)), model.AddVertex(new Vector3(size, size, 0)), new Rectangle(0, 0, 10, 10)); _drawableKK = new DrawableModel(model, imageFloor, GraphicsDevice, false); ModelSearch.AddModel(_levelSearch, model); model = new KModel(); var boxes = new List<Vector3> { new Vector3(1, 1, 0), new Vector3(2, 1, 0), new Vector3(2, 1, 1), new Vector3(2, 1, 2), new Vector3(3, 1, 0), new Vector3(3, 1, 1), new Vector3(3, 1, 2), new Vector3(-2, 1, 0), new Vector3(-2, 1, 1), new Vector3(-3, -3, 0), new Vector3(-3, -3, 1), new Vector3(-3, -3, 2), new Vector3(-3, -3, 3), new Vector3(-3, -6, 0), new Vector3(-3, -6, 1), new Vector3(-3, -6, 2), new Vector3(-3, -6, 3), new Vector3(-3, -4, 3), new Vector3(-3, -5, 3), }; for (int j = 0; j < 5; j++) for (int i = -20; i < 20; i++) { //boxes.Add(new Vector3(i, -20, j)); boxes.Add(new Vector3(-20, i + 1, j)); boxes.Add(new Vector3(i + 1, 20, j)); boxes.Add(new Vector3(20, i, j)); } foreach (var corner in boxes) model.AddBox(new BoundingBox(corner, corner + new Vector3(1, 1, 1)), new Rectangle(0, 128, 225, 225), false); /* model.AddBox(new BoundingBox(new Vector3(3, 3, 1), new Vector3(5, 5, 3)), new Rectangle(0, 0, 64, 64), true); model.AddBox(new BoundingBox(new Vector3(-5, -5, 1), new Vector3(-3, -3, 3)), new Rectangle(0, 0, 64, 64), true); */ model.AddBox(new BoundingBox(new Vector3(2, -5, 0), new Vector3(2, -5, 0) + new Vector3(2.5f, 2.5f, 2.5f)), new Rectangle(0, 128, 225, 225), false); _drawableBox = new DrawableModel(model, imageBox, GraphicsDevice, false); ModelSearch.AddModel(_levelSearch, model); model = GeometricalPrimitives.CreateBall(2, new Rectangle(0, 0, 1, 1)); model.TexCoordsAreInPixels = false; _drawableBall = new DrawableModel(model, imageBall, GraphicsDevice, true); model = GeometricalPrimitives.CreateSpikyBall(3, 0.2f, new Rectangle(0, 0, 1, 1)); model.TexCoordsAreInPixels = false; _drawableSpikyBall = new DrawableModel(model, imageSpikyBall, GraphicsDevice, true); SceneRenderer.EnableShadows(GraphicsDevice, Content.Load<Effect>(@"Shaders\ShadowCasting"), 4, 2048); InitLights(); }