public void Initialize() { var importer = new AssimpContext(); var aScene = importer.ImportFile(FilePath, PostProcessPreset.TargetRealTimeMaximumQuality); Meshes = new List <Mesh>(); foreach (var aMesh in aScene.Meshes) { var verticesResult = new List <MeshSkinnedVerticeInfo>(); var indicesResult = new List <int>(); var mesh = new Mesh(); mesh.Bones = new List <Bone>(); mesh.Name = aMesh.Name; Dictionary <int, List <VerticeWeight> > VerticeWeights = new Dictionary <int, List <VerticeWeight> >(); foreach (var aBone in aMesh.Bones) { Bone bone = GetBone(mesh, aBone); foreach (var vw in aBone.VertexWeights) { if (!VerticeWeights.ContainsKey(vw.VertexID)) { VerticeWeights.Add(vw.VertexID, new List <VerticeWeight>()); } VerticeWeights[vw.VertexID].Add(new VerticeWeight() { Bone = bone, Weight = vw.Weight }); } } var c = aScene.Materials[aMesh.MaterialIndex].ColorDiffuse; for (int faceIndex = 0; faceIndex < aMesh.FaceCount; faceIndex++) { for (int vertexNum = 0; vertexNum < 3; vertexNum++) { int verticeIndice = aMesh.Faces[faceIndex].Indices[vertexNum]; Vector3 verticePosition = AssimpHelper.VectorAssimpToXna(aMesh.Vertices[verticeIndice]); Vector3 verticeNormal = AssimpHelper.VectorAssimpToXna(aMesh.Normals[verticeIndice]); var uv = AssimpHelper.VectorAssimpToXna(aMesh.TextureCoordinateChannels[0][verticeIndice]); var verticeUv = new Vector2(uv.X, uv.Y); BlendInfo blendInfo = GetBlendInfo(VerticeWeights, verticeIndice); var vertice = new MeshSkinnedVerticeInfo() { Position = verticePosition, Normal = verticeNormal, TextureCoordinate = verticeUv, BoneID = blendInfo.BoneId, BoneWeight = blendInfo.Weight }; indicesResult.Add(verticesResult.Count); verticesResult.Add(vertice); } } mesh.TextureFilePath = aScene.Materials[aMesh.MaterialIndex].TextureDiffuse.FilePath; mesh.VertexBuffer = new VertexBuffer(GraphicsDevice, typeof(SkinnedModelVertex), verticesResult.Count, BufferUsage.WriteOnly); mesh.VertexBuffer.SetData <SkinnedModelVertex>(verticesResult.Select(v => v.ToVertexPositionNormalTextureBones()).ToArray()); mesh.IndexBuffer = new IndexBuffer(GraphicsDevice, typeof(int), indicesResult.Count, BufferUsage.WriteOnly); mesh.IndexBuffer.SetData(indicesResult.ToArray()); mesh.FaceCount = aMesh.FaceCount; Meshes.Add(mesh); } }
/* * input kernel area naming convention: * ------------- | A | B | C | | ----|---|---| | D | E | F | //input pixel is at position E | ----|---|---| | G | H | I | | ------------- */ private static void _ScalePixel( IScaler scaler, RotationDegree rotDeg, Kernel_3X3 ker, sPixel[] trg, int trgi, int trgWidth, byte blendInfo, //result of preprocessing all four corners of pixel "e" IColorEq scalePixelColorEq, IColorDist scalePixelColorDist, OutputMatrix outputMatrix ) { //int a = kernel._[Rot._[(0 << 2) + rotDeg]]; var b = ker._[Rot._[(1 << 2) + (int)rotDeg]]; var c = ker._[Rot._[(2 << 2) + (int)rotDeg]]; var d = ker._[Rot._[(3 << 2) + (int)rotDeg]]; var e = ker._[Rot._[(4 << 2) + (int)rotDeg]]; var f = ker._[Rot._[(5 << 2) + (int)rotDeg]]; var g = ker._[Rot._[(6 << 2) + (int)rotDeg]]; var h = ker._[Rot._[(7 << 2) + (int)rotDeg]]; var i = ker._[Rot._[(8 << 2) + (int)rotDeg]]; var blend = BlendInfo.Rotate(blendInfo, rotDeg); if (BlendInfo.GetBottomR(blend) == BlendType.BlendNone) { return; } var eq = scalePixelColorEq; var dist = scalePixelColorDist; bool doLineBlend; if (BlendInfo.GetBottomR(blend) >= BlendType.BlendDominant) { doLineBlend = true; } //make sure there is no second blending in an adjacent //rotation for this pixel: handles insular pixels, mario eyes //but support double-blending for 90? corners else if (BlendInfo.GetTopR(blend) != BlendType.BlendNone && !eq._(e, g)) { doLineBlend = false; } else if (BlendInfo.GetBottomL(blend) != BlendType.BlendNone && !eq._(e, c)) { doLineBlend = false; } //no full blending for L-shapes; blend corner only (handles "mario mushroom eyes") else if (eq._(g, h) && eq._(h, i) && eq._(i, f) && eq._(f, c) && !eq._(e, i)) { doLineBlend = false; } else { doLineBlend = true; } //choose most similar color var px = dist._(e, f) <= dist._(e, h) ? f : h; var output = outputMatrix; output.Move(rotDeg, trgi); if (!doLineBlend) { scaler.BlendCorner(px, output); return; } //test sample: 70% of values max(fg, hc) / min(fg, hc) //are between 1.1 and 3.7 with median being 1.9 var fg = dist._(f, g); var hc = dist._(h, c); var haveShallowLine = _CONFIGURATION.steepDirectionThreshold * fg <= hc && e != g && d != g; var haveSteepLine = _CONFIGURATION.steepDirectionThreshold * hc <= fg && e != c && b != c; if (haveShallowLine) { if (haveSteepLine) { scaler.BlendLineSteepAndShallow(px, output); } else { scaler.BlendLineShallow(px, output); } } else { if (haveSteepLine) { scaler.BlendLineSteep(px, output); } else { scaler.BlendLineDiagonal(px, output); } } }
public static void ScaleImage(ScaleSize scaleSize, sPixel[] src, sPixel[] trg, int srcWidth, int srcHeight, int xFirst, int yFirst, int xLast, int yLast) { yFirst = Math.Max(yFirst, 0); yLast = Math.Min(yLast, srcHeight); if (yFirst >= yLast || srcWidth <= 0) { return; } var trgWidth = srcWidth * scaleSize.size; //temporary buffer for "on the fly preprocessing" var preProcBuffer = new byte[srcWidth]; var ker4 = new Kernel_4X4(); var preProcessCornersColorDist = new ColorDistA(); //initialize preprocessing buffer for first row: //detect upper left and right corner blending //this cannot be optimized for adjacent processing //stripes; we must not allow for a memory race condition! if (yFirst > 0) { var y = yFirst - 1; var sM1 = srcWidth * Math.Max(y - 1, 0); var s0 = srcWidth * y; //center line var sP1 = srcWidth * Math.Min(y + 1, srcHeight - 1); var sP2 = srcWidth * Math.Min(y + 2, srcHeight - 1); for (var x = xFirst; x < xLast; ++x) { var xM1 = Math.Max(x - 1, 0); var xP1 = Math.Min(x + 1, srcWidth - 1); var xP2 = Math.Min(x + 2, srcWidth - 1); //read sequentially from memory as far as possible ker4.b = src[sM1 + x]; ker4.c = src[sM1 + xP1]; ker4.e = src[s0 + xM1]; ker4.f = src[s0 + x]; ker4.g = src[s0 + xP1]; ker4.h = src[s0 + xP2]; ker4.i = src[sP1 + xM1]; ker4.j = src[sP1 + x]; ker4.k = src[sP1 + xP1]; ker4.l = src[sP1 + xP2]; ker4.n = src[sP2 + x]; ker4.o = src[sP2 + xP1]; var blendResult = new BlendResult(); _PreProcessCorners(ker4, blendResult, preProcessCornersColorDist); // writes to blendResult /* * preprocessing blend result: * --------- | F | G | //evalute corner between F, G, J, K | ----|---| //input pixel is at position F | J | K | | --------- */ preProcBuffer[x] = BlendInfo.SetTopR(preProcBuffer[x], blendResult.j); if (x + 1 < srcWidth) { preProcBuffer[x + 1] = BlendInfo.SetTopL(preProcBuffer[x + 1], blendResult.k); } } } var eqColorThres = _Square(_CONFIGURATION.equalColorTolerance); var scalePixelColorEq = new ColorEqA(eqColorThres); var scalePixelColorDist = new ColorDistA(); var outputMatrix = new OutputMatrix(scaleSize.size, trg, trgWidth); var ker3 = new Kernel_3X3(); for (var y = yFirst; y < yLast; ++y) { //consider MT "striped" access var trgi = scaleSize.size * y * trgWidth; var sM1 = srcWidth * Math.Max(y - 1, 0); var s0 = srcWidth * y; //center line var sP1 = srcWidth * Math.Min(y + 1, srcHeight - 1); var sP2 = srcWidth * Math.Min(y + 2, srcHeight - 1); byte blendXy1 = 0; for (var x = xFirst; x < xLast; ++x, trgi += scaleSize.size) { var xM1 = Math.Max(x - 1, 0); var xP1 = Math.Min(x + 1, srcWidth - 1); var xP2 = Math.Min(x + 2, srcWidth - 1); //evaluate the four corners on bottom-right of current pixel //blend_xy for current (x, y) position byte blendXy; { //read sequentially from memory as far as possible ker4.b = src[sM1 + x]; ker4.c = src[sM1 + xP1]; ker4.e = src[s0 + xM1]; ker4.f = src[s0 + x]; ker4.g = src[s0 + xP1]; ker4.h = src[s0 + xP2]; ker4.i = src[sP1 + xM1]; ker4.j = src[sP1 + x]; ker4.k = src[sP1 + xP1]; ker4.l = src[sP1 + xP2]; ker4.n = src[sP2 + x]; ker4.o = src[sP2 + xP1]; var blendResult = new BlendResult(); _PreProcessCorners(ker4, blendResult, preProcessCornersColorDist); // writes to blendResult /* * preprocessing blend result: * --------- | F | G | //evaluate corner between F, G, J, K | ----|---| //current input pixel is at position F | J | K | | --------- */ //all four corners of (x, y) have been determined at //this point due to processing sequence! blendXy = BlendInfo.SetBottomR(preProcBuffer[x], blendResult.f); //set 2nd known corner for (x, y + 1) blendXy1 = BlendInfo.SetTopR(blendXy1, blendResult.j); //store on current buffer position for use on next row preProcBuffer[x] = blendXy1; //set 1st known corner for (x + 1, y + 1) and //buffer for use on next column blendXy1 = BlendInfo.SetTopL(0, blendResult.k); if (x + 1 < srcWidth) { //set 3rd known corner for (x + 1, y) preProcBuffer[x + 1] = BlendInfo.SetBottomL(preProcBuffer[x + 1], blendResult.g); } } //fill block of size scale * scale with the given color // //place *after* preprocessing step, to not overwrite the // //results while processing the the last pixel! _FillBlock(trg, trgi, trgWidth, src[s0 + x], scaleSize.size); //blend four corners of current pixel if (blendXy == 0) { continue; } const int a = 0, b = 1, c = 2, d = 3, e = 4, f = 5, g = 6, h = 7, i = 8; //read sequentially from memory as far as possible ker3._[a] = src[sM1 + xM1]; ker3._[b] = src[sM1 + x]; ker3._[c] = src[sM1 + xP1]; ker3._[d] = src[s0 + xM1]; ker3._[e] = src[s0 + x]; ker3._[f] = src[s0 + xP1]; ker3._[g] = src[sP1 + xM1]; ker3._[h] = src[sP1 + x]; ker3._[i] = src[sP1 + xP1]; _ScalePixel(scaleSize.scaler, RotationDegree.Rot0, ker3, trg, trgi, trgWidth, blendXy, scalePixelColorEq, scalePixelColorDist, outputMatrix); _ScalePixel(scaleSize.scaler, RotationDegree.Rot90, ker3, trg, trgi, trgWidth, blendXy, scalePixelColorEq, scalePixelColorDist, outputMatrix); _ScalePixel(scaleSize.scaler, RotationDegree.Rot180, ker3, trg, trgi, trgWidth, blendXy, scalePixelColorEq, scalePixelColorDist, outputMatrix); _ScalePixel(scaleSize.scaler, RotationDegree.Rot270, ker3, trg, trgi, trgWidth, blendXy, scalePixelColorEq, scalePixelColorDist, outputMatrix); } } }
public void WriteToFile(BinaryWriter writer) { //BEFORE WE WRITE, WE NEED TO COMPILE AND UPDATE THE FRAME. UpdateFrameData(); header.WriteToFile(writer); foreach (var Geometry in frameGeometries.Values) { Geometry.WriteToFile(writer); } foreach (var Material in frameMaterials.Values) { Material.WriteToFile(writer); } foreach (var BlendInfo in frameBlendInfos.Values) { BlendInfo.WriteToFile(writer); } foreach (var Skeleton in frameSkeletons.Values) { Skeleton.WriteToFile(writer); } foreach (var SkeletonHierarchy in frameSkeletonHierachies.Values) { SkeletonHierarchy.WriteToFile(writer); } foreach (var FObject in frameObjects.Values) { FrameObjectBase entry = (FObject as FrameObjectBase); if (entry.GetType() == typeof(FrameObjectJoint)) { writer.Write((int)ObjectType.Joint); } else if (entry.GetType() == typeof(FrameObjectSingleMesh)) { writer.Write((int)ObjectType.SingleMesh); } else if (entry.GetType() == typeof(FrameObjectFrame)) { writer.Write((int)ObjectType.Frame); } else if (entry.GetType() == typeof(FrameObjectLight)) { writer.Write((int)ObjectType.Light); } else if (entry.GetType() == typeof(FrameObjectCamera)) { writer.Write((int)ObjectType.Camera); } else if (entry.GetType() == typeof(FrameObjectComponent_U005)) { writer.Write((int)ObjectType.Component_U00000005); } else if (entry.GetType() == typeof(FrameObjectSector)) { writer.Write((int)ObjectType.Sector); } else if (entry.GetType() == typeof(FrameObjectDummy)) { writer.Write((int)ObjectType.Dummy); } else if (entry.GetType() == typeof(FrameObjectDeflector)) { writer.Write((int)ObjectType.ParticleDeflector); } else if (entry.GetType() == typeof(FrameObjectArea)) { writer.Write((int)ObjectType.Area); } else if (entry.GetType() == typeof(FrameObjectTarget)) { writer.Write((int)ObjectType.Target); } else if (entry.GetType() == typeof(FrameObjectModel)) { writer.Write((int)ObjectType.Model); } else if (entry.GetType() == typeof(FrameObjectCollision)) { writer.Write((int)ObjectType.Collision); } } foreach (var FObject in frameObjects.Values) { FrameObjectBase entry = (FObject as FrameObjectBase); entry.WriteToFile(writer); } }