123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247 |
- #region License
- // Copyright 2015-2016 Kastellanos Nikolaos
- //
- // Licensed under the Apache License, Version 2.0 (the "License");
- // you may not use this file except in compliance with the License.
- // You may obtain a copy of the License at
- //
- // http://www.apache.org/licenses/LICENSE-2.0
- //
- // Unless required by applicable law or agreed to in writing, software
- // distributed under the License is distributed on an "AS IS" BASIS,
- // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- // See the License for the specific language governing permissions and
- // limitations under the License.
- #endregion
- using System;
- using System.Collections.Generic;
- using System.IO;
- using Microsoft.Xna.Framework;
- using Microsoft.Xna.Framework.Content.Pipeline;
- using Microsoft.Xna.Framework.Content.Pipeline.Graphics;
- using Microsoft.Xna.Framework.Graphics;
- namespace nkast.Aether.Content.Pipeline
- {
- [ContentImporter(".vox", DisplayName = "Voxel Model Importer - Aether", DefaultProcessor = "ModelProcessor")]
- public class VoxelModelImporter : ContentImporter<NodeContent>
- {
- public override NodeContent Import(string filename, ContentImporterContext context)
- {
- VoxelContent voxel = null;
- if (Path.GetExtension(filename) == ".vox")
- {
- VoxImporter voxelImporter = new VoxImporter();
- voxel = voxelImporter.ImportVox(filename, context);
- }
- else
- {
- throw new InvalidContentException("File type not supported.");
- }
-
- voxel.MarkSharedSides();
- voxel.RemoveHiddenBlocks();
-
- NodeContent output = VoxelProcess(voxel, context);
-
- return output;
- }
- /// <summary>
- /// Import a VOX file as Model
- /// </summary>
- private NodeContent VoxelProcess(VoxelContent voxel, ContentImporterContext context)
- {
- XYZI[] voxels = voxel.Voxels;
- uint[] palette = voxel.Palette;
- Vector3 scale = voxel.RealSize / voxel.GridSize;
- Vector3 centerOffset = new Vector3(1f, 1f, 1f) * (voxel.RealSize / -2f);
- Point3 corner000 = new Point3(0, 0, 0);
- Point3 corner100 = new Point3(1, 0, 0);
- Point3 corner010 = new Point3(0, 1, 0);
- Point3 corner110 = new Point3(1, 1, 0);
- Point3 corner001 = new Point3(0, 0, 1);
- Point3 corner101 = new Point3(1, 0, 1);
- Point3 corner011 = new Point3(0, 1, 1);
- Point3 corner111 = new Point3(1, 1, 1);
- Vector3 Forward = Vector3.Forward;
- Vector3 Backward = Vector3.Backward;
- Vector3 Left = Vector3.Left;
- Vector3 Right = Vector3.Right;
- Vector3 Up = Vector3.Up;
- Vector3 Down = Vector3.Down;
- for (int i = 0; i < voxels.Length; i++)
- {
- Point3 pt000 = voxels[i].Point.Add(ref corner000);
- Point3 pt100 = voxels[i].Point.Add(ref corner100);
- Point3 pt010 = voxels[i].Point.Add(ref corner010);
- Point3 pt110 = voxels[i].Point.Add(ref corner110);
- Point3 pt001 = voxels[i].Point.Add(ref corner001);
- Point3 pt101 = voxels[i].Point.Add(ref corner101);
- Point3 pt011 = voxels[i].Point.Add(ref corner011);
- Point3 pt111 = voxels[i].Point.Add(ref corner111);
- // back
- Vector3 p0 = pt000.ToVector3();
- Vector3 p1 = pt100.ToVector3();
- Vector3 p2 = pt010.ToVector3();
- Vector3 p3 = pt110.ToVector3();
- // front
- Vector3 p4 = pt001.ToVector3();
- Vector3 p5 = pt101.ToVector3();
- Vector3 p6 = pt011.ToVector3();
- Vector3 p7 = pt111.ToVector3();
- Vector3.Multiply(ref p0, ref scale, out p0); Vector3.Add(ref p0, ref centerOffset, out p0);
- Vector3.Multiply(ref p1, ref scale, out p1); Vector3.Add(ref p1, ref centerOffset, out p1);
- Vector3.Multiply(ref p2, ref scale, out p2); Vector3.Add(ref p2, ref centerOffset, out p2);
- Vector3.Multiply(ref p3, ref scale, out p3); Vector3.Add(ref p3, ref centerOffset, out p3);
- Vector3.Multiply(ref p4, ref scale, out p4); Vector3.Add(ref p4, ref centerOffset, out p4);
- Vector3.Multiply(ref p5, ref scale, out p5); Vector3.Add(ref p5, ref centerOffset, out p5);
- Vector3.Multiply(ref p6, ref scale, out p6); Vector3.Add(ref p6, ref centerOffset, out p6);
- Vector3.Multiply(ref p7, ref scale, out p7); Vector3.Add(ref p7, ref centerOffset, out p7);
- vertex.Color.PackedValue = palette[voxels[i].ColorIndex];
- if ((voxels[i].SharedSides & Sides.Forward) == 0)
- {
- vertex.Normal = Forward;
- AddVertex(ref p1);
- AddVertex(ref p3);
- AddVertex(ref p0);
- AddVertex(ref p0);
- AddVertex(ref p3);
- AddVertex(ref p2);
- }
- if ((voxels[i].SharedSides & Sides.Backward) == 0)
- {
- vertex.Normal = Backward;
- AddVertex(ref p4);
- AddVertex(ref p6);
- AddVertex(ref p5);
- AddVertex(ref p5);
- AddVertex(ref p6);
- AddVertex(ref p7);
- }
- if ((voxels[i].SharedSides & Sides.Left) == 0)
- {
- vertex.Normal = Left;
- AddVertex(ref p2);
- AddVertex(ref p6);
- AddVertex(ref p0);
- AddVertex(ref p0);
- AddVertex(ref p6);
- AddVertex(ref p4);
- }
- if ((voxels[i].SharedSides & Sides.Right) == 0)
- {
- vertex.Normal = Right;
- AddVertex(ref p1);
- AddVertex(ref p5);
- AddVertex(ref p3);
- AddVertex(ref p3);
- AddVertex(ref p5);
- AddVertex(ref p7);
- }
- if ((voxels[i].SharedSides & Sides.Up) == 0)
- {
- vertex.Normal = Up;
- AddVertex(ref p7);
- AddVertex(ref p6);
- AddVertex(ref p3);
- AddVertex(ref p3);
- AddVertex(ref p6);
- AddVertex(ref p2);
- }
- if ((voxels[i].SharedSides & Sides.Down) == 0)
- {
- vertex.Normal = Down;
- AddVertex(ref p5);
- AddVertex(ref p1);
- AddVertex(ref p4);
- AddVertex(ref p4);
- AddVertex(ref p1);
- AddVertex(ref p0);
- }
- }
- MeshContent mesh = new MeshContent();
- mesh.Name = "voxel";
- for (int pi = 0; pi < this.vertices.Count; pi++)
- {
- mesh.Positions.Add(this.vertices[pi].Position);
- }
- GeometryContent geom = new GeometryContent();
- mesh.Geometry.Add(geom);
- BasicMaterialContent material = new BasicMaterialContent();
- geom.Material = material;
- for (int pi = 0; pi < this.vertices.Count; pi++)
- {
- geom.Vertices.Add(pi);
- }
- for (int ii = 0; ii < this.indices.Count; ii++)
- {
- geom.Indices.Add(this.indices[ii]);
- }
- List<Vector3> normals = new List<Vector3>();
- List<Color> colors = new List<Color>();
- for (int vi = 0; vi < this.vertices.Count; vi++)
- {
- var vertex = vertices[vi];
- normals.Add(vertex.Normal);
- colors.Add(vertex.Color);
- }
- geom.Vertices.Channels.Add<Vector3>(VertexChannelNames.Normal(0), normals);
- geom.Vertices.Channels.Add<Color>(VertexChannelNames.Color(0), colors);
- return mesh;
- }
- List<VertexPositionNormalColor> vertices = new List<VertexPositionNormalColor>();
- List<int> indices = new List<int>();
- Dictionary<VertexPositionNormalColor, int> vertexMap = new Dictionary<VertexPositionNormalColor, int>();
- VertexPositionNormalColor vertex;
- private int AddVertex(ref Vector3 position)
- {
- vertex.Position = position;
- int vertIndx;
- if (!vertexMap.TryGetValue(vertex, out vertIndx))
- {
- vertIndx = vertices.Count;
- vertices.Add(vertex);
- vertexMap.Add(vertex, vertIndx);
- }
- indices.Add(vertIndx);
- return vertIndx;
- }
- }
- }
|