public static bool CreatePartMorphInfo(List <Vector3> vertices, RenderMeshPart part, float scale, out PartMorphInfo info) { var result = new PartMorphInfo(); var pointnsDict = new Dictionary <Vector3, int>(new VectorEqualityComparer()); foreach (var v in vertices) { if (!pointnsDict.ContainsKey(v)) { pointnsDict.Add(v, result.PointsMorph.Count); result.PointsMorph.Add(v); } } if (result.PointsMorph.Count != part.Points.Count) { info = null; return(false); } for (int i = 0; i < result.PointsMorph.Count; i++) { var index = part.Points[i].Indices[0]; var p = (part.BaseVertices ?? part.Vertices)[index].OriginalPosition; result.PointsMorph[i] = result.PointsMorph[i] - p / scale; } info = result; return(true); }
private void ProcessPart(RenderMeshPart part, List <int> startPoints, List <float> distance, bool isMirrored = false) { if (shapedParts.ContainsKey(part.Guid)) { return; } shapedParts.Add(part.Guid, part); var nextParts = new Dictionary <Guid, ShapePartInfo>(); for (var i = 0; i < startPoints.Count; i++) { var index = startPoints[i]; var p = part.Points[index]; if (!shapePoints.ContainsKey(p.Position)) { shapePoints.Add(p.Position, new ShapePointData()); } var sp = shapePoints[p.Position]; sp.PartsPoints.Add(new KeyValuePair <RenderMeshPart, int>(part, index)); sp.Distance = Math.Min(sp.Distance, distance[i]); sp.IsMirrored = isMirrored; } for (var i = 0; i < startPoints.Count; i++) { ProcessPoint(part, startPoints[i], distance[i], ref nextParts, isMirrored); } foreach (var pt in nextParts) { var p = headMeshController.RenderMesh.Parts.First(r => r.Guid.Equals(pt.Key)); ProcessPart(p, pt.Value.Points, pt.Value.Distance, isMirrored); } }
public MeshInfo(RenderMeshPart part, float scale = 1.0f) { var positionsMapping = new Dictionary <Vector3, int>(new VectorEqualityComparer()); var texCoordsMapping = new Dictionary <Vector2, int>(new VectorEqualityComparer()); var normalsMapping = new Dictionary <Vector3, int>(new VectorEqualityComparer()); foreach (var index in part.Indices) { var vertex = part.Vertices[index]; var position = vertex.Position; var texCoord = vertex.TexCoord; texCoord.Y = 1.0f - texCoord.Y; var normal = vertex.Normal; int id; if (!positionsMapping.TryGetValue(position, out id)) { id = Positions.Count; Positions.Add(position); positionsMapping.Add(position, id); } IndicesPositions.Add(id); if (!normalsMapping.TryGetValue(normal, out id)) { id = Normals.Count; Normals.Add(normal); normalsMapping.Add(normal, id); } IndicesNormals.Add(id); if (!texCoordsMapping.TryGetValue(texCoord, out id)) { id = TexCoords.Count; TexCoords.Add(texCoord); texCoordsMapping.Add(texCoord, id); } IndicesTexCoords.Add(id); } for (var i = 0; i < Positions.Count; ++i) { Positions[i] = Positions[i] * scale; } Title = part.Name; // Material = new ObjMaterial(part.Guid.ToString().Replace("-", "")); Material.DiffuseColor = part.Color; Material.Texture = part.Texture; Material.TransparentTexture = part.TransparentTexture; #if WEB_APP Material.DiffuseTextureMap = ProgramCore.Project.RenderMainHelper.GetTexturePath(part.Texture); Material.TransparentTextureMap = ProgramCore.Project.RenderMainHelper.GetTexturePath(part.TransparentTexture); #else Material.DiffuseTextureMap = ProgramCore.MainForm.ctrlRenderControl.GetTexturePath(part.Texture); Material.TransparentTextureMap = ProgramCore.MainForm.ctrlRenderControl.GetTexturePath(part.TransparentTexture); #endif }
public void UpdateAABB(RenderMeshPart part, ref Vector3 a, ref Vector3 b) { foreach (var vertex in part.Vertices) { a.Z = Math.Min(vertex.Position.Z, a.Z); b.Z = Math.Max(vertex.Position.Z, b.Z); } }
public void add(MeshPart part, vec3 pos, quat rot) { RenderMeshPart d = new RenderMeshPart(); d.part = part; d.pos = pos; d.rot = rot; datas.Add(d); }
public void AddPart(RenderMeshPart part) { Parts.Add(part); var a = AABB.A; var b = AABB.B; UpdateAABB(part, ref a, ref b); AABB.A = a; AABB.B = b; }
public bool CreateMeshPart(MeshPartInfo info) { var part = new RenderMeshPart(); if (part.Create(info)) { RenderMesh.AddPart(part); return true; } return false; }
public bool CreateMeshPart(MeshPartInfo info) { var part = new RenderMeshPart(); if (part.Create(info)) { RenderMesh.AddPart(part); return(true); } return(false); }
public bool CreateMeshPart(GenesisType genesis, MeshPartInfo info) { var part = new RenderMeshPart(); if (part.Create(genesis, info)) { RenderMesh.AddPart(part); return(true); } return(false); }
private static void MorphPart(RenderMeshPart part, IList<PartMorphInfo> morphInfos) { var count = morphInfos.Any() ? 1.0f / morphInfos.Count() : 1.0f; if (part.IsMirrored) { var verticesDictionary = new Dictionary<uint, Vector3>(); for (var i = 0; i < part.Points.Count; i++) { var point = part.Points[i]; var delta = morphInfos.Aggregate(Vector3.Zero, (current, mi) => current + mi.PointsMorph[i] * mi.Delta) * count; foreach (var index in point.Indices) { if (!verticesDictionary.ContainsKey(index)) verticesDictionary.Add(index, delta); } } for (var i = 0; i < part.Vertices.Length; i++) { var vertex = part.Vertices[i]; if (vertex.OriginalPosition.X >= 0.0f && vertex.OriginalPosition.X <= 1.0f) { var a = (uint)Math.Abs(vertex.OriginalPosition.Y); var b = (uint)Math.Abs(vertex.OriginalPosition.Z); var point0 = part.BaseVertices[a].Position + verticesDictionary[a]; var point1 = part.BaseVertices[b].Position + verticesDictionary[b]; vertex.Position = point0 + (point1 - point0) * vertex.OriginalPosition.X; } else { var p = (uint)Math.Abs(vertex.OriginalPosition.X) - 2; var delta = verticesDictionary[p]; vertex.Position = part.BaseVertices[p].Position + delta; if (vertex.Position.X > 0.0f == part.IsLeftToRight) vertex.Position.X = 0.0f; if (vertex.OriginalPosition.X < 0.0f) vertex.Position.X *= -1.0f; } part.Vertices[i] = vertex; } } else { for (var i = 0; i < part.Points.Count; i++) { var point = part.Points[i]; var delta = morphInfos.Aggregate(Vector3.Zero, (current, mi) => current + mi.PointsMorph[i] * mi.Delta) * count; foreach (var index in point.Indices) part.Vertices[index].Position = point.Position + delta; } } part.UpdateNormals(); }
public void Load(string path) { if (!File.Exists(path)) { return; } Parts.Clear(); using (var br = new BinaryReader(File.Open(path, FileMode.Open))) { AABB = RectangleAABB.FromStream(br); Scale = Vector2Ex.FromStream(br); Center = Vector2Ex.FromStream(br); var cnt = br.ReadInt32(); for (var i = 0; i < cnt; i++) { Parts.Add(RenderMeshPart.FromStream(br)); } } }
public void InitializeTexCoords(ref Vector2 v1, ref Vector2 v2, ref Vector2 v3, ref Vector2 vm1, ref Vector2 vm2, ref Vector2 vm3, RenderMeshPart meshPart) { foreach (var i in Indices) { var v = meshPart.Vertices[i]; v.AutodotsTexCoord.X = FrontTriangle.U * v1.X + FrontTriangle.V * v2.X + FrontTriangle.W * v3.X; v.AutodotsTexCoord.Y = FrontTriangle.U * v1.Y + FrontTriangle.V * v2.Y + FrontTriangle.W * v3.Y; if (meshPart.IsTextureMirrored()) { v.AutodotsTexCoord.Z = FrontTriangle.U * vm1.X + FrontTriangle.V * vm2.X + FrontTriangle.W * vm3.X; v.AutodotsTexCoord.W = FrontTriangle.U * vm1.Y + FrontTriangle.V * vm2.Y + FrontTriangle.W * vm3.Y; } else { v.AutodotsTexCoord.Z = v.AutodotsTexCoord.X; v.AutodotsTexCoord.W = v.AutodotsTexCoord.Y; } meshPart.Vertices[i] = v; } }
public void EndShape() { ClearSelection(); startPart = null; startTriangle = -1; }
private void ProcessPoint(RenderMeshPart part, int p, float distance, ref Dictionary <Guid, ShapePartInfo> nextParts, bool isMirrored = false) { var point = part.Points[p]; var nearest = new Dictionary <int, float>(); foreach (var n in point.Nearests) { var pos = part.Points[n].Position; if (isMirrored && pos.X * isLeft < 0.0f) { continue; } var dist = (pos - point.Position).Length + distance; nearest.Add(n, dist); } //Берем все точки в радиусе заданном var where = nearest.Where(r => r.Value < shapeRadius).ToList(); foreach (var n in where) { //оставляем только те у которых уменьшилась дистанция var pt = part.Points[n.Key]; if (shapePoints.ContainsKey(pt.Position)) { var sp = shapePoints[pt.Position]; if (sp.PartsPoints.FindIndex(r => r.Value.Equals(n.Key) && r.Key.Guid.Equals(part.Guid)) < 0) { sp.PartsPoints.Add(new KeyValuePair <RenderMeshPart, int>(part, n.Key)); } else { if (sp.Distance <= n.Value) { nearest[n.Key] = 10000.0f; } } sp.Distance = Math.Min(sp.Distance, n.Value); sp.IsMirrored = isMirrored; } //или новые точки else { var sp = new ShapePointData(); sp.Distance = n.Value; sp.IsMirrored = isMirrored; sp.PartsPoints.Add(new KeyValuePair <RenderMeshPart, int>(part, n.Key)); shapePoints.Add(pt.Position, sp); } } foreach (var n in nearest.Where(r => r.Value < shapeRadius)) { var np = part.Points[n.Key]; foreach (var prt in headMeshController.RenderMesh.Parts.Where(r => r.Guid != part.Guid)) { var id = -1; if (prt.PointsIndices.TryGetValue(np, out id)) { if (nextParts.ContainsKey(prt.Guid)) { var nextPart = nextParts[prt.Guid]; if (!nextPart.Points.Contains(id)) { nextPart.Points.Add(id); nextPart.Distance.Add(n.Value); } else { var i = nextPart.Points.IndexOf(id); nextPart.Distance[i] = Math.Min(nextPart.Distance[i], n.Value); } } else { nextParts.Add(prt.Guid, new ShapePartInfo { Distance = new List <float> { n.Value }, Points = new List <int> { id } }); } } } } foreach (var n in nearest.Where(r => r.Value < shapeRadius)) { ProcessPoint(part, n.Key, n.Value, ref nextParts, isMirrored); } }
public static bool CreatePartMorphInfo(List<Vector3> vertices, RenderMeshPart part, float scale, out PartMorphInfo info) { var result = new PartMorphInfo(); var pointnsDict = new Dictionary<Vector3, int>(new VectorEqualityComparer()); foreach (var v in vertices) { if (!pointnsDict.ContainsKey(v)) { pointnsDict.Add(v, result.PointsMorph.Count); result.PointsMorph.Add(v); } } if (result.PointsMorph.Count != part.Points.Count) { info = null; return false; } for (var i = 0; i < result.PointsMorph.Count; i++) { var index = part.Points[i].Indices[0]; var p = (part.BaseVertices ?? part.Vertices)[index].OriginalPosition; result.PointsMorph[i] = result.PointsMorph[i] - p / scale; } info = result; return true; }
private static void MorphPart(RenderMeshPart part, IList <PartMorphInfo> morphInfos) { var count = morphInfos.Any() ? 1.0f / morphInfos.Count() : 1.0f; if (part.IsMirrored) { var verticesDictionary = new Dictionary <uint, Vector3>(); for (int i = 0; i < part.Points.Count; i++) { var point = part.Points[i]; var delta = morphInfos.Aggregate(Vector3.Zero, (current, mi) => current + mi.PointsMorph[i] * mi.Delta) * count; foreach (var index in point.Indices) { if (!verticesDictionary.ContainsKey(index)) { verticesDictionary.Add(index, delta); } } } for (int i = 0; i < part.Vertices.Length; i++) { var vertex = part.Vertices[i]; if (vertex.OriginalPosition.X >= 0.0f && vertex.OriginalPosition.X <= 1.0f) { var a = (uint)Math.Abs(vertex.OriginalPosition.Y); var b = (uint)Math.Abs(vertex.OriginalPosition.Z); var point0 = part.BaseVertices[a].Position + verticesDictionary[a]; var point1 = part.BaseVertices[b].Position + verticesDictionary[b]; vertex.Position = point0 + (point1 - point0) * vertex.OriginalPosition.X; } else { var p = (uint)Math.Abs(vertex.OriginalPosition.X) - 2; var delta = verticesDictionary[p]; vertex.Position = part.BaseVertices[p].Position + delta; if (vertex.Position.X > 0.0f == part.IsLeftToRight) { vertex.Position.X = 0.0f; } if (vertex.OriginalPosition.X < 0.0f) { vertex.Position.X *= -1.0f; } } part.Vertices[i] = vertex; } } else { for (int i = 0; i < part.Points.Count; i++) { var point = part.Points[i]; var delta = morphInfos.Aggregate(Vector3.Zero, (current, mi) => current + mi.PointsMorph[i] * mi.Delta) * count; foreach (var index in point.Indices) { part.Vertices[index].Position = point.Position + delta; } } } part.UpdateNormals(); }
public float StartShaping(Vector3 point, Matrix4 vm, bool isMirror, float radius, ShapeCoefType type) { EndShape(); var depth = -10000.0f; foreach (var part in headMeshController.RenderMesh.Parts) { for (var i = 0; i < part.Indices.Count; i += 3) { var p0 = Vector3.Transform(part.Vertices[part.Indices[i]].Position, vm); var p1 = Vector3.Transform(part.Vertices[part.Indices[i + 1]].Position, vm); var p2 = Vector3.Transform(part.Vertices[part.Indices[i + 2]].Position, vm); var a = p0.Xy; var b = p1.Xy; var c = p2.Xy; if (TexturingInfo.PointInTriangle(ref a, ref b, ref c, ref point)) { var aup = a.X - point.X; var bup = b.X - point.X; var cup = c.X - point.X; var avp = a.Y - point.Y; var bvp = b.Y - point.Y; var cvp = c.Y - point.Y; var f = 1.0f / ((b.X - a.X) * (c.Y - a.Y) - (b.Y - a.Y) * (c.X - a.X)); var u = (bup * cvp - bvp * cup) * f; var v = (cup * avp - cvp * aup) * f; var w = 1.0f - (u + v); var z = u * p0.Z + v * p1.Z + w * p2.Z; if (depth < z) { startPart = part; startTriangle = i; depth = z; } } } } if (startPart == null || startTriangle < 0) { return(0.0f); } ShapePoint = point; ShapePoint.Z = depth; ShapePoint = Vector3.Transform(ShapePoint, vm.Inverted()); startTriangleMirror = -1; if (isMirror) { //Ищем точку в оригинальных координатах var triangle = new[] { startPart.Indices[startTriangle], startPart.Indices[startTriangle + 1], startPart.Indices[startTriangle + 2] }; var a = startPart.Vertices[triangle[0]].OriginalPosition; var b = startPart.Vertices[triangle[1]].OriginalPosition; var c = startPart.Vertices[triangle[2]].OriginalPosition; a.X *= -1.0f; b.X *= -1.0f; c.X *= -1.0f; isLeft = ShapePoint.X < 0.0f ? 1.0f : -1.0f; int idA = -1, idB = -1, idC = -1; for (var i = 0; i < startPart.Vertices.Length; i++) { if (idA >= 0 && idB >= 0 && idC >= 0) { break; } var position = startPart.Vertices[i].OriginalPosition; if (position.X * isLeft >= 0.0f) { if (idA < 0 && VectorEqualityComparer.EqualsVector3(position, a)) { idA = i; continue; } if (idB < 0 && VectorEqualityComparer.EqualsVector3(position, b)) { idB = i; continue; } if (idC < 0 && VectorEqualityComparer.EqualsVector3(position, c)) { idC = i; continue; } } } if (idA >= 0 && idB >= 0 && idC >= 0) { for (var i = 0; i < startPart.Indices.Count; i += 3) { var v0 = startPart.Indices[i]; var v1 = startPart.Indices[i + 1]; var v2 = startPart.Indices[i + 2]; if ((v0 == idA || v0 == idB || v0 == idC) && (v1 == idA || v1 == idB || v1 == idC) && (v2 == idA || v2 == idB || v2 == idC)) { startTriangleMirror = i; break; } } } } if (!UpdateRadius(radius)) { return(0.0f); } UpdateCoef(type, radius); return(depth); }
private void RenderMesh_OnBeforePartDraw(RenderMeshPart part) { var transparent = UseTexture ? (float)part.TransparentTexture : 0.0f; if (transparent > 0.0f) EnableTransparent(); else DisableTransparent(); var shader = idleShader; var useTextures = Vector3.Zero; if (brushTextures.ContainsKey(part.Texture)) { GL.ActiveTexture(TextureUnit.Texture2); GL.BindTexture(TextureTarget.Texture2D, brushTextures[part.Texture].Texture); shader.UpdateUniform("u_BrushMap", 2); useTextures.Z = 1.0f; } GL.ActiveTexture(TextureUnit.Texture1); GL.BindTexture(TextureTarget.Texture2D, part.TransparentTexture); shader.UpdateUniform("u_TransparentMap", 1); //shader.UpdateUniform("u_UseTransparent", transparent); useTextures.Y = transparent; if (!ProgramCore.PluginMode) { GL.ActiveTexture(TextureUnit.Texture0); GL.BindTexture(TextureTarget.Texture2D, part.Texture); shader.UpdateUniform("u_Texture", 0); useTextures.X = UseTexture ? part.Texture : 0.0f; //shader.UpdateUniform("u_UseTexture", UseTexture ? part.Texture : 0.0f); shader.UpdateUniform("u_Color", part.Color); } else { GL.ActiveTexture(TextureUnit.Texture0); var pName = part.Name.ToLower(); var texture = ProgramCore.Project.ManType != ManType.Custom || ProgramCore.MainForm.PluginUvGroups.Contains(pName) ? part.Texture : 0; GL.BindTexture(TextureTarget.Texture2D, texture); shader.UpdateUniform("u_Texture", 0); useTextures.X = UseTexture ? texture : 0.0f; //shader.UpdateUniform("u_UseTexture", UseTexture ? texture : 0.0f); shader.UpdateUniform("u_Color", part.Color); } shader.UpdateUniform("u_UseTexture", useTextures); }
private void DrawTrianlges(Graphics g, int width, int height, RenderMeshPart part, Bitmap newTexture) { Vector2i t0 = new Vector2i(); Vector2i t1 = new Vector2i(); Vector2i t2 = new Vector2i(); Vector2 uv0 = new Vector2(); Vector2 uv1 = new Vector2(); Vector2 uv2 = new Vector2(); var newWidth = newTexture.Width - 1; var newHeight = newTexture.Height - 1; var brush = new SolidBrush(RandomColor()); const float u_BlendStartDepth = -0.5f; const float u_BlendDepth = 4f; for (int index = 0; index < part.Indices.Count; index += 3) { var v0 = part.Vertices[part.Indices[index]]; var v1 = part.Vertices[part.Indices[index + 1]]; var v2 = part.Vertices[part.Indices[index + 2]]; if (v0.TexCoord.Y > v1.TexCoord.Y) { Swap(ref v0, ref v1); } if (v0.TexCoord.Y > v2.TexCoord.Y) { Swap(ref v0, ref v2); } if (v1.TexCoord.Y > v2.TexCoord.Y) { Swap(ref v1, ref v2); } t0.X = (int)Math.Round(v0.TexCoord.X * width); t0.Y = (int)Math.Round(v0.TexCoord.Y * height); t1.X = (int)Math.Round(v1.TexCoord.X * width); t1.Y = (int)Math.Round(v1.TexCoord.Y * height); t2.X = (int)Math.Round(v2.TexCoord.X * width); t2.Y = (int)Math.Round(v2.TexCoord.Y * height); uv0.X = Clamp(v0.AutodotsTexCoord.X, 0f, 1f) * newWidth; uv0.Y = Clamp(v0.AutodotsTexCoord.Y, 0f, 1f) * newHeight; uv1.X = Clamp(v1.AutodotsTexCoord.X, 0f, 1f) * newWidth; uv1.Y = Clamp(v1.AutodotsTexCoord.Y, 0f, 1f) * newHeight; uv2.X = Clamp(v2.AutodotsTexCoord.X, 0f, 1f) * newWidth; uv2.Y = Clamp(v2.AutodotsTexCoord.Y, 0f, 1f) * newHeight; var blend0 = Clamp(v0.AutodotsTexCoord.Z * (v0.Position.Z - u_BlendStartDepth) / u_BlendDepth, 0f, 1f); var blend1 = Clamp(v1.AutodotsTexCoord.Z * (v1.Position.Z - u_BlendStartDepth) / u_BlendDepth, 0f, 1f); var blend2 = Clamp(v2.AutodotsTexCoord.Z * (v2.Position.Z - u_BlendStartDepth) / u_BlendDepth, 0f, 1f); //if (blend0 == 0f && blend1 == 0f && blend2 == 0f) // continue; if (t0.Y == t1.Y && t0.Y == t2.Y) { continue; } var total_height = t2.Y - t0.Y; for (int i = 0; i < total_height; i++) { bool second_half = i > (t1.Y - t0.Y) || t1.Y == t0.Y; int segment_height = second_half ? (t2.Y - t1.Y) : (t1.Y - t0.Y); float alpha = (float)i / total_height; float beta = (float)(i - (second_half ? (t1.Y - t0.Y) : 0)) / segment_height; var a = t0 + (t2 - t0) * alpha; var b = second_half ? t1 + (t2 - t1) * beta : t0 + (t1 - t0) * beta; var uvA = uv0 + (uv2 - uv0) * alpha; var uvB = second_half ? uv1 + (uv2 - uv1) * beta : uv0 + (uv1 - uv0) * beta; var blendA = blend0 + (blend2 - blend0) * alpha; var blendB = second_half ? blend1 + (blend2 - blend1) * beta : blend0 + (blend1 - blend0) * beta; if (a.X > b.X) { Swap(ref a, ref b); Swap(ref uvA, ref uvB); } var ax = a.X; var bx = b.X; for (int j = ax; j <= bx; j++) { float phi = b.X == a.X ? 1f : (j - a.X) / (float)(b.X - a.X); var uvP = uvA + (uvB - uvA) * phi; var blend = blendA + (blendB - blendA) * phi; var invBlend = 1f - blend; var color = newTexture.GetPixel((int)uvP.X, (int)uvP.Y); var resultColor = Color.FromArgb((int)(blend * 255), color.R, color.G, color.B); g.FillRectangle(new SolidBrush(resultColor), j, t0.Y + i, 1, 1); } } } }