public Raytracing( Canvas canvas, Scene scene, V3 cameraPos, int maxDepth ) : base(canvas, scene, cameraPos) { MaxDepth = maxDepth; }
/// Renders the scene. public override void Render() { Canvas.BeginDrawing(); for (int x = 0 ; x < Canvas.Width ; x++) { for (int y = 0 ; y < Canvas.Height ; y++) { V3 p = new V3(x, 0, y); Color color = Raytrace( new Ray( origin: CameraPos, direction: p - CameraPos ), MaxDepth ); if (color != null) { V3 pScreen = new V3(x, Canvas.Height - y, 0); Canvas.DrawPixel(pScreen, color); } } } Canvas.EndDrawing(); }
public virtual Color Compute( List<Light> lights, Object3D obj, V3 p, V2 uv ) { Color illumination = new Color(0, 0, 0); foreach (Light l in lights) { if (l.GetType().Name == "AmbientLight") { illumination += ComputeAmbientLight( (AmbientLight) l, obj, p, uv ); } else if (l.GetType().Name == "PointLight") { illumination += ComputePointLight( (PointLight) l, obj, p, uv ); } else if (l.GetType().Name == "DirectionalLight") { illumination += ComputeDirectionalLight( (DirectionalLight) l, obj, p, uv ); } } return illumination; }
public override V3 Normal(V3 p) { V3 n = p - Center; n.Normalize(); return n; }
static void Main () { V2 a = new V2 (); V3 b = new V3 (); V2 s = a - b; }
/// Returns the altered normal if this object possesses a bump map, or /// the unaltered one if it does not. public V3 Normal(V3 p, V2 uv) { if (Material.BumpMap != null) { return AlteredNormal(p, uv); } return Normal(p); }
/// Computes the diffuse and specular components of the Phong /// reflection model for a directional light. public override Color ComputeDirectionalLight( DirectionalLight dL, Object3D obj, V3 p, V2 uv ) { V3 incidentVec = -dL.Direction; return ComputeDiffuseSpecular(dL, obj, p, uv, incidentVec); }
/// Computes the diffuse and specular components of the Phong /// reflection model for a point light. public override Color ComputePointLight( PointLight pL, Object3D obj, V3 p, V2 uv ) { V3 incidentVec = pL.Position - p; incidentVec.Normalize(); return ComputeDiffuseSpecular(pL, obj, p, uv, incidentVec); }
public override Tuple<V3, V3> DerivativePoint(V2 uv) { V3 dPdu = new V3(VA); dPdu.Normalize(); V3 dPdv = new V3(VB); dPdv.Normalize(); return new Tuple<V3,V3>(dPdu, dPdv); }
private Color ComputeDiffuse( Light l, V3 incidentVec, V3 normalVec, Object3D obj, V2 uv ) { Color diffuseIllu = new Color(0, 0, 0); if (incidentVec * normalVec > 0.0f) { diffuseIllu = obj.TextureColor(uv) * l.Intensity * obj.Material.KDiffuse * (incidentVec * normalVec); } return diffuseIllu; }
public Rectangle(V3 center, V3 va, V3 vb, PhongMaterial material) : base(center, material) { if (va * vb != 0) { throw new Exception( "Not a rectangle (VA: " + va + ", VB: " + vb + ")." ); } VA = va; VB = vb; }
public override Tuple<V3, V3> DerivativePoint(V2 uv) { V2 uvS = UV(uv); // uv sphere V3 dPdu = new V3( x: -Radius * Mathf.Cos(uvS.V) * Mathf.Sin(uvS.U), y: Radius * Mathf.Cos(uvS.V) * Mathf.Cos(uvS.U), z: 0 ); dPdu.Normalize(); V3 dPdv = new V3( x: -Radius * Mathf.Sin(uvS.V) * Mathf.Cos(uvS.U), y: -Radius * Mathf.Sin(uvS.V) * Mathf.Sin(uvS.U), z: Radius * Mathf.Cos(uvS.V) ); dPdv.Normalize(); return new Tuple<V3,V3>(dPdu, dPdv); }
/// Computes the diffuse and specular components of the Phong /// reflection model. /// @Note Avoids code duplication in ComputePointLight and /// ComputeDirectionalLight. private Color ComputeDiffuseSpecular( Light l, Object3D obj, V3 p, V2 uv, V3 incidentVec ) { V3 normalVec = obj.Normal(p, uv); V3 reflectedVec = incidentVec.ReflectedVector(normalVec); reflectedVec.Normalize(); V3 viewingVec = CameraPos - p; viewingVec.Normalize(); Color diffuseIllu = ComputeDiffuse( l, incidentVec, normalVec, obj, uv ); Color specularIllu = ComputeSpecular( l, reflectedVec, normalVec, obj, uv ); return diffuseIllu + specularIllu; }
/// Renders one object. private void RenderObject(Object3D obj) { for (float u = 0.0f ; u < 1.0f ; u += 0.001f) { for (float v = 0.0f ; v < 1.0f ; v += 0.001f) { V2 uv = new V2(u,v); V3 p = obj.Point(uv); V3 pScreen = new V3( x: p.X, y: Canvas.Height - p.Z, z: p.Y ); bool objectVisible = Set(pScreen); if (objectVisible) { Color illumination = Scene.IlluModel.Compute( Scene.Lights, obj, p, uv ); Canvas.DrawPixel(pScreen, illumination); } } } }
/// <summary> /// Parses the Wavefront Object file at the provided path and returns the operation's result. /// </summary> public static ImportResult Import(string path, IPXPmxBuilder builder, ImportSettings settings, IOProgress progress) { // Cancel the process if needed if (progress.CancellationToken.IsCancellationRequested) { progress.CancellationToken.ThrowIfCancellationRequested(); } IPXPmx pmx = builder.Pmx(); pmx.Clear(); pmx.ModelInfo.ModelName = pmx.ModelInfo.ModelNameE = Path.GetFileNameWithoutExtension(path); pmx.ModelInfo.Comment = pmx.ModelInfo.CommentE = "(Imported from OBJ by WPlugins.ObjIO)"; StreamReader reader = null; System.Globalization.NumberFormatInfo fi = System.Globalization.NumberFormatInfo.InvariantInfo; System.Globalization.NumberStyles ns = System.Globalization.NumberStyles.Float; // Model elements List <V3> vList = new List <V3>(); List <V2> vtList = new List <V2>(); List <V3> vnList = new List <V3>(); Dictionary <Tuple <int, int, int>, int> vertexDictionary = new Dictionary <Tuple <int, int, int>, int>(); Dictionary <string, IPXMaterial> materials = new Dictionary <string, IPXMaterial>(); IPXMaterial currentMaterial = null; // Values derived from settings V3 positionScale = new V3(settings.ScaleX, settings.ScaleY, settings.ScaleZ) * (settings.UseMetricUnits ? 0.254f : 0.1f); // Statistics int lineNumber = 0; try { reader = new StreamReader(path); char[] separator = { ' ' }; while (!reader.EndOfStream) { System.Threading.Thread.Sleep(2); // Cancel the process if needed if (progress.CancellationToken.IsCancellationRequested) { progress.CancellationToken.ThrowIfCancellationRequested(); } string line = reader.ReadLine().Trim(); ++lineNumber; ++progress.LineNumber; progress.Report(IOProgress.Percent(reader.BaseStream.Position, reader.BaseStream.Length)); // Skip empty lines and comments if (string.IsNullOrWhiteSpace(line) || line[0] == '#') { continue; } string[] split = line.Split(separator, StringSplitOptions.RemoveEmptyEntries); switch (split[0]) { // Vertex position case "v": try { float x = float.Parse(split[1], ns, fi); float y = float.Parse(split[2], ns, fi); float z = float.Parse(split[3], ns, fi); vList.Add(new V3(x, y, -z)); } catch (FormatException ex) { if (progress.ReportError(string.Format("A format exception has occured: {0}", line))) { return(ImportResult.Fail(ex, progress.WarningCount, progress.ErrorCount)); } vList.Add(new V3()); } break; // Vertex texture coordinates case "vt": try { // Technically this can be a V3 or any vector, but PMX only uses the first two elements for the main UV channel. float x = float.Parse(split[1], ns, fi); float y = float.Parse(split[2], ns, fi); vtList.Add(new V2(x, -y)); } catch (FormatException ex) { if (progress.ReportError(string.Format("A format exception has occured: {0}", line))) { return(ImportResult.Fail(ex, progress.WarningCount, progress.ErrorCount)); } vtList.Add(new V2()); } break; // Vertex normal case "vn": try { float x = float.Parse(split[1], ns, fi); float y = float.Parse(split[2], ns, fi); float z = float.Parse(split[3], ns, fi); vnList.Add(new V3(x, y, -z)); } catch (FormatException ex) { if (progress.ReportError(string.Format("A format exception has occured: {0}", line))) { return(ImportResult.Fail(ex, progress.WarningCount, progress.ErrorCount)); } vnList.Add(new V3()); } break; // Face definition case "f": if (currentMaterial == null) { progress.ReportWarning(string.Format("Encountered a face record when no active group was set.", lineNumber)); currentMaterial = builder.Material(); } // Triangle if (split.Length == 4) { int v = 0; int vt = 0; int vn = 0; bool newVertex; try { // Split each vertex assignment triple into its respective v/vt/vn indices. GetVertexElements(split[1], out v, out vt, out vn); // Based on the indices, determine if the vertex assignment is unique or already exists. A vertex is considered unique if one or more index is different, regardless of the vectors they represent. newVertex = GetUniqueVertex(v, vt, vn, vertexDictionary, pmx.Vertex.Count, out int index1); if (newVertex) { IPXVertex vert = builder.Vertex(); pmx.Vertex.Add(vert); // The new vertex is added to the end of the list, making its index equal to the list's count before the addition. if (v >= 0) { vert.Position = vList[v] * positionScale; } if (vt >= 0) { vert.UV = vtList[vt]; } if (vn >= 0) { vert.Normal = vnList[vn]; } } IPXVertex vertex1 = pmx.Vertex[index1]; // Repeat the same process for the rest of the vertex triples. GetVertexElements(split[2], out v, out vt, out vn); newVertex = GetUniqueVertex(v, vt, vn, vertexDictionary, pmx.Vertex.Count, out int index2); if (newVertex) { IPXVertex vert = builder.Vertex(); pmx.Vertex.Add(vert); if (v >= 0) { vert.Position = vList[v] * positionScale; } if (vt >= 0) { vert.UV = vtList[vt]; } if (vn >= 0) { vert.Normal = vnList[vn]; } } IPXVertex vertex2 = pmx.Vertex[index2]; GetVertexElements(split[3], out v, out vt, out vn); newVertex = GetUniqueVertex(v, vt, vn, vertexDictionary, pmx.Vertex.Count, out int index3); if (newVertex) { IPXVertex vert = builder.Vertex(); pmx.Vertex.Add(vert); if (v >= 0) { vert.Position = vList[v] * positionScale; } if (vt >= 0) { vert.UV = vtList[vt]; } if (vn >= 0) { vert.Normal = vnList[vn]; } } IPXVertex vertex3 = pmx.Vertex[index3]; // Build the triangle and assign the vertices; use reverse order and negative normal vectors if the triangles are reversed. IPXFace face = builder.Face(); if (settings.FlipFaces) { vertex1.Normal *= -1; vertex2.Normal *= -1; vertex3.Normal *= -1; face.Vertex1 = vertex1; face.Vertex2 = vertex2; face.Vertex3 = vertex3; } else { face.Vertex1 = vertex3; face.Vertex2 = vertex2; face.Vertex3 = vertex1; } currentMaterial.Faces.Add(face); } catch (Exception ex) { if (progress.ReportError(ex.ToString())) { return(ImportResult.Fail(ex, progress.WarningCount, progress.ErrorCount)); } } } // Quad else if (split.Length == 5) { int v = 0; int vt = 0; int vn = 0; bool newVertex; try { GetVertexElements(split[1], out v, out vt, out vn); newVertex = GetUniqueVertex(v, vt, vn, vertexDictionary, pmx.Vertex.Count, out int index1); if (newVertex) { IPXVertex vert = builder.Vertex(); pmx.Vertex.Add(vert); if (v >= 0) { vert.Position = vList[v] * positionScale; } if (vt >= 0) { vert.UV = vtList[vt]; } if (vn >= 0) { vert.Normal = vnList[vn]; } } IPXVertex vertex1 = pmx.Vertex[index1]; GetVertexElements(split[2], out v, out vt, out vn); newVertex = GetUniqueVertex(v, vt, vn, vertexDictionary, pmx.Vertex.Count, out int index2); if (newVertex) { IPXVertex vert = builder.Vertex(); pmx.Vertex.Add(vert); if (v >= 0) { vert.Position = vList[v] * positionScale; } if (vt >= 0) { vert.UV = vtList[vt]; } if (vn >= 0) { vert.Normal = vnList[vn]; } } IPXVertex vertex2 = pmx.Vertex[index2]; GetVertexElements(split[3], out v, out vt, out vn); newVertex = GetUniqueVertex(v, vt, vn, vertexDictionary, pmx.Vertex.Count, out int index3); if (newVertex) { IPXVertex vert = builder.Vertex(); pmx.Vertex.Add(vert); if (v >= 0) { vert.Position = vList[v] * positionScale; } if (vt >= 0) { vert.UV = vtList[vt]; } if (vn >= 0) { vert.Normal = vnList[vn]; } } IPXVertex vertex3 = pmx.Vertex[index3]; GetVertexElements(split[4], out v, out vt, out vn); newVertex = GetUniqueVertex(v, vt, vn, vertexDictionary, pmx.Vertex.Count, out int index4); if (newVertex) { IPXVertex vert = builder.Vertex(); pmx.Vertex.Add(vert); if (v >= 0) { vert.Position = vList[v] * positionScale; } if (vt >= 0) { vert.UV = vtList[vt]; } if (vn >= 0) { vert.Normal = vnList[vn]; } } IPXVertex vertex4 = pmx.Vertex[index4]; int faceIndex1 = 0, faceIndex2 = 0; IPXFace face = builder.Face(); if (settings.FlipFaces) { face.Vertex3 = settings.TurnQuads ? vertex3 : vertex4; face.Vertex2 = vertex2; face.Vertex1 = vertex1; currentMaterial.Faces.Add(face); faceIndex1 = currentMaterial.Faces.Count - 1; face = builder.Face(); face.Vertex1 = settings.TurnQuads ? vertex1 : vertex2; face.Vertex2 = vertex3; face.Vertex3 = vertex4; currentMaterial.Faces.Add(face); faceIndex2 = currentMaterial.Faces.Count - 1; } else { face.Vertex1 = settings.TurnQuads ? vertex3 : vertex4; face.Vertex2 = vertex2; face.Vertex3 = vertex1; currentMaterial.Faces.Add(face); faceIndex1 = currentMaterial.Faces.Count - 1; face = builder.Face(); face.Vertex3 = settings.TurnQuads ? vertex1 : vertex2; face.Vertex2 = vertex3; face.Vertex1 = vertex4; currentMaterial.Faces.Add(face); faceIndex2 = currentMaterial.Faces.Count - 1; } if (settings.SaveTrianglePairs) { currentMaterial.Memo += string.Format("({0},{1})", faceIndex1, faceIndex2); } } catch (Exception ex) { if (progress.ReportError(ex.ToString())) { return(ImportResult.Fail(ex, progress.WarningCount, progress.ErrorCount)); } } } else { if (progress.ReportError(string.Format("The OBJ file contains a polygon with an invalid number of vertices. Currently only triangles and quads are supported. Line content: {0}", line))) { return(ImportResult.Fail(new InvalidOperationException("Invalid polygon"), progress.WarningCount, progress.ErrorCount)); } } break; // Group assignment defines which PMX object (IPXMaterial instance) the subsequent faces belong to. case "g": currentMaterial = builder.Material(); currentMaterial.Name = currentMaterial.NameE = line.Trim().Substring(2); progress.Report("New object: " + currentMaterial.Name); pmx.Material.Add(currentMaterial); // Set default properties currentMaterial.Diffuse = new V4(1, 1, 1, 1); currentMaterial.Ambient = new V3(0.5f, 0.5f, 0.5f); break; // Material assignment defines which material template should be applied to the currently active PMX object. Any number of PMX objects can refer to a single material template. case "usemtl": if (currentMaterial == null) { progress.ReportWarning(string.Format("Encountered a material template reference when no active group was set.", lineNumber)); currentMaterial = builder.Material(); } { string name = line.Trim().Substring(7); IPXMaterial m = currentMaterial; // Active material IPXMaterial t = materials[name]; // Template material m.Diffuse = t.Diffuse; m.Specular = t.Specular; m.Power = t.Power; m.Ambient = t.Ambient; m.Diffuse = t.Diffuse; m.SelfShadow = t.SelfShadow; m.SelfShadowMap = t.SelfShadowMap; m.Shadow = t.Shadow; m.Tex = t.Tex; m.EdgeSize = t.EdgeSize; m.EdgeColor = t.EdgeColor; m.Edge = t.Edge; } break; // Material library, may occur multiple times in a model. case "mtllib": string materialLibraryName = line.Substring(7); progress.Report("Importing materials from " + materialLibraryName); // Try relative path string materialLibraryPath = Path.Combine(Path.GetDirectoryName(path), materialLibraryName); if (!File.Exists(materialLibraryPath)) { // Try absolute path materialLibraryPath = materialLibraryName; if (!File.Exists(materialLibraryPath)) { progress.ReportError(string.Format("Material library not found ({0}).", materialLibraryName)); break; } } Dictionary <string, IPXMaterial> tempDict = ImportMaterials(materialLibraryPath, builder, settings, progress); foreach (KeyValuePair <string, IPXMaterial> kvp in tempDict) { if (materials.ContainsKey(kvp.Key)) { progress.ReportWarning(string.Format("Duplicate material {0} imported from {1} has been discarded.", kvp.Key, materialLibraryName)); } else { materials.Add(kvp.Key, kvp.Value); } } progress.Report(string.Format("Imported {0} materials from {1}.", tempDict.Count, materialLibraryName)); break; // Smoothing group assignment (unused) case "s": break; default: break; } } // Second pass for bone weights and transformations because I'm lazy IPXBone bone = null; if (settings.CreateBone != ImportSettings.CreateBoneMode.None) { bone = builder.Bone(); bone.Name = bone.NameE = pmx.ModelInfo.ModelName.Replace(' ', '_'); } foreach (IPXVertex vertex in pmx.Vertex) { // Bone if (settings.CreateBone == ImportSettings.CreateBoneMode.Average) { bone.Position += vertex.Position; } vertex.Bone1 = settings.CreateBone != ImportSettings.CreateBoneMode.None ? bone : null; vertex.Weight1 = 1.0f; vertex.Bone2 = vertex.Bone3 = vertex.Bone4 = null; vertex.Weight2 = vertex.Weight3 = vertex.Weight4 = 0; // Axis swap if (settings.SwapYZ) { float temp = vertex.Position.Y; vertex.Position.Y = vertex.Position.Z; vertex.Position.Z = temp; temp = vertex.Normal.Y; vertex.Normal.Y = vertex.Normal.Z; vertex.Normal.Z = temp; } } if (settings.CreateBone == ImportSettings.CreateBoneMode.Average) { bone.Position /= pmx.Vertex.Count; } } catch (OperationCanceledException) { throw; } catch (Exception ex) { if (progress.ReportError(ex.ToString())) { return(ImportResult.Fail(ex, progress.WarningCount, progress.ErrorCount)); } } finally { if (reader != null) { reader.Close(); reader = null; } } return(ImportResult.Success(pmx, progress.WarningCount, progress.ErrorCount)); }
public override V2 UV(V3 p) { V3 d = p - Center; V3 van = new V3(VA); van.Normalize(); V3 vbn = new V3(VB); vbn.Normalize(); // u = ||d -> VA|| / ||VA|| float u = ((d * van) / VA.Norm1()); // v = ||d -> VB|| / ||VB|| float v = ((d * vbn) / VB.Norm1()); // u & v: [-0.5 ; 0.5] -> [0;1] u += 0.5f; v += 0.5f; return new V2(u,v); }
/// <summary> /// 将三角形的三个点进行平移 /// </summary> /// <param name="translation"></param> /// <param name="distance"></param> /// <returns></returns> public Triangle Translate(Vector3d translation, double distance) { return(new Triangle(V1.Move(translation, distance), V2.Move(translation, distance), V3.Move(translation, distance))); }
public Root(TwitchAPI api) { v3 = new V3(api); v5 = new V5(api); }
public Streams(TwitchAPI api) { v3 = new V3(api); v5 = new V5(api); helix = new Helix(api); }
public abstract Color ComputePointLight( PointLight pL, Object3D obj, V3 p, V2 uv );
public Sphere(V3 center, float radius, PhongMaterial material) : base(center, material) { Radius = radius; }
// Create a physics chain that fits onto the bone chain public static void GeneratePhysics(IPXPmxBuilder builder, IPXBone[] bones, PhysicsSettings settings, out IPXBody[] rigidbodies, out IPXJoint[] joints) { rigidbodies = new IPXBody[bones.Length - 1]; joints = new IPXJoint[bones.Length - 2]; for (int i = 0; i < rigidbodies.Length; ++i) { // Basic setup IPXBody b = rigidbodies[i] = builder.Body(); b.Position = Vector3.Average(bones[i].Position, bones[i + 1].Position); b.Bone = bones[i]; b.Name = b.Bone.Name; b.NameE = b.Bone.NameE; b.Mode = settings.BodyMode; // Size b.BoxKind = settings.Shape; float w = settings.Width; float h = settings.Height; float length; switch (settings.LengthCalculation) { case PhysicsSettings.LengthCalculationMode.Relative: length = Vector3.Distance(bones[i].Position, bones[i + 1].Position) * settings.Length; break; case PhysicsSettings.LengthCalculationMode.DistanceFromEnds: length = Math.Max(Vector3.Distance(bones[i].Position, bones[i + 1].Position) - settings.Length * 2, 0); break; default: length = settings.Length; break; } if (settings.Shape == PEPlugin.Pmd.BodyBoxKind.Sphere) { b.BoxSize = new V3(length / 2.0f, 1, 1); } else { b.BoxSize = new Vector3(w, length / 2.0f, h); } // Angle V3 dir = bones[i + 1].Position - bones[i].Position; dir.Normalize(); float heading = Mathf.Atan2(dir.X, dir.Z); float theta = -heading; V3 elev = new V3(Mathf.Cos(theta) * dir.X + Mathf.Sin(theta) * dir.Z, dir.Y, -Mathf.Sin(theta) * dir.X + Mathf.Cos(theta) * dir.Z); b.Rotation = new V3(Mathf.Atan2(elev.Z, elev.Y), heading, 0); } for (int i = 0; i < joints.Length; ++i) { IPXJoint j = joints[i] = builder.Joint(); j.Position = bones[i + 1].Position; j.BodyA = rigidbodies[i]; j.BodyB = rigidbodies[i + 1]; j.Name = j.BodyA.Name; j.NameE = j.BodyA.NameE; } }
public abstract Color ComputeDirectionalLight( DirectionalLight dL, Object3D obj, V3 p, V2 uv );
// エントリポイント public override void Run(IPERunArgs args) { try { //PMD/PMXファイルを操作するためにおまじない。 this.host = args.Host; this.builder = this.host.Builder; this.bd = this.host.Builder.SC; this.connect = this.host.Connector; this.pex = this.connect.Pmd.GetCurrentStateEx(); this.PMD = this.connect.Pmd.GetCurrentState(); this.PMX = this.connect.Pmx.GetCurrentState(); this.Form = this.connect.Form; this.PMDView = this.connect.View.PMDView; //-----------------------------------------------------------ここから----------------------------------------------------------- //ここから処理開始 //-----------------------------------------------------------ここから----------------------------------------------------------- if (this.connect.Form.PmxFormActivate) { for (int i = 0; i < this.PMX.Vertex.Count; i++) { IPXVertex vertex = this.PMX.Vertex[i]; V3 vp = (V3)vertex.Position; int ind1, ind2; ind1 = ind2 = -1; float dis1, dis2; dis1 = dis2 = 10000000; for (int j = 0; j < this.PMX.Bone.Count; j++) { IPXBone bone = this.PMX.Bone[j]; V3 bp = (V3)bone.Position; float dis; if (bone.ToBone == null) { continue; } else { dis = getDistanceBoneToVertex(bone, vertex); } if (dis < dis1) { dis2 = dis1; ind2 = ind1; ind1 = j; dis1 = dis; } else if (dis < dis2) { dis2 = dis; ind2 = j; } } if (ind1 >= 0) { vertex.Bone1 = this.PMX.Bone[ind1]; vertex.Weight1 = 1.0f; } if (ind2 >= 0) { vertex.Bone2 = this.PMX.Bone[ind2]; #if MODE_EXCLUSIVE vertex.Weight2 = 0f; #else vertex.Weight2 = (1f * dis1 / (dis1 + dis2)); vertex.Weight1 = 1.0f - vertex.Weight2; #endif } } } else { for (int i = 0; i < this.PMD.Vertex.Count; i++) { IPEVertex vertex = this.PMD.Vertex[i]; V3 vp = (V3)vertex.Position; int ind1, ind2; ind1 = ind2 = -1; float dis1, dis2; dis1 = dis2 = 10000000; for (int j = 0; j < this.PMD.Bone.Count; j++) { IPEBone bone = this.PMD.Bone[j]; V3 bp = (V3)bone.Position; float dis; if (bone.To == -1 || bone.To == 0) { continue; } else { dis = getDistanceBoneToVertex(bone, vertex); } // float dis = (bp - vp).Length(); if (dis < dis1) { dis2 = dis1; ind2 = ind1; ind1 = j; dis1 = dis; } else if (dis < dis2) { dis2 = dis; ind2 = j; } } if (ind1 >= 0) { vertex.Bone1 = ind1; } if (ind2 >= 0) { vertex.Bone2 = ind2; #if MODE_EXCLUSIVE vertex.Weight = 100; #else vertex.Weight = (int)(100f * dis2 / (dis1 + dis2)); #endif } } } //-----------------------------------------------------------ここまで----------------------------------------------------------- //処理ここまで //-----------------------------------------------------------ここまで----------------------------------------------------------- //モデル・画面を更新します。 this.Update(); #if MODE_EXCLUSIVE MessageBox.Show(this.PMD.Vertex.Count.ToString() + "個の頂点のウェイトを最短排他形式で設定しました。", "ウェイト自動設定(排他的)", MessageBoxButtons.OK, MessageBoxIcon.Information); #else MessageBox.Show(this.PMX.Vertex.Count.ToString() + "個の頂点のウェイトを中間補完形式で設定しました。", "ウェイト自動設定(補完的)", MessageBoxButtons.OK, MessageBoxIcon.Information); #endif } catch (Exception ex) { MessageBox.Show(ex.Message, "エラー", MessageBoxButtons.OK, MessageBoxIcon.Exclamation); } }
public static V3 Cross(V3 a, V3 b) { V3 v = new V3(a.Y * b.Z - b.Y * a.Z, a.Z * b.X - b.Z * a.X, a.X * b.Y - b.X * a.Y); return(v); }
public static float Dot(V3 a, V3 b) { return(a.X * b.X + a.Y * b.Y + a.Z * b.Z); }
public void DrawPixel(V3 pScreen, Color c) { DrawPixel((int) pScreen.X, (int) pScreen.Y, c); }
public abstract Couleur applyLight(Object3D b, V3 positionLight, V3 normal, Couleur color_surface);
public static float Dot(V3 a, V3 b) { return a.X * b.X + a.Y * b.Y + a.Z * b.Z; }
public static Tuple <double, double, double> ToTuple(this V3 param) { return(new Tuple <double, double, double>(param.X, param.Y, param.Z)); }
static public Point3d V3ToPoint3d(V3 pos) { return(new Point3d(pos.x, pos.y, pos.z)); }
// This method is the callback by which the forests controlled // by the scene manager tell us about SpeedTrees. private void AddTreeObstacles(SpeedTreeWrapper tree) { // If this tree didn't use to be in range but now is V3 vp = tree.TreePosition; Vector3 p = new Vector3(vp.x, vp.y, vp.z); // Find the tile in question int tileX, tileZ; WorldToTileCoords(p, out tileX, out tileZ); bool oir = InRange(tileXCenter, tileZCenter, tileX, tileZ); bool nir = InRange(newTileXCenter, newTileZCenter, tileX, tileZ); // if (MO.DoLog) // MO.Log(String.Format("For tree at {0}, testing !InRange({1},{2},{3},{4}) = {5} && InRange({6},{7},{8},{9}) = {10}", // MO.MeterString(p),tileXCenter, tileZCenter, tileX, tileZ, MO.Bool(!oir), // newTileXCenter, newTileZCenter, tileX, tileZ, MO.Bool(nir))); if (!oir && nir) { int tX = TileToArrayIndex(tileX, newTileXCenter); int tZ = TileToArrayIndex(tileZ, newTileZCenter); uint count = tree.CollisionObjectCount; long handle = ComposeHandle(tileX, tileZ); CollisionShape shape = null; if (MO.DoLog) { MO.Log(string.Format("Adding tree at {0}, tiles[{1},{2}] = {3}, tile coords[{4},{5}], obj. new count {6}", MO.MeterString(p), tX, tZ, tiles[tX, tZ], tileX, tileZ, count)); MO.Log(string.Format("Handle {0}, oldcenter {1}, newcenter {2}", MO.HandleString(handle), MO.MeterString(tileWorldCenter), MO.MeterString(newTileWorldCenter))); } float size = 0f; float variance = 0f; tree.GetTreeSize(ref size, ref variance); float scaleFactor = size / tree.OriginalSize; for (uint i = 0; i < count; i++) { TreeCollisionObject tco = tree.CollisionObject(i); Vector3 cp = new Vector3(tco.position.x, tco.position.y, tco.position.z) * scaleFactor + p; Vector3 cd = new Vector3(tco.dimensions.x, tco.dimensions.y, tco.dimensions.z) * scaleFactor; switch ((CollisionObjectType)tco.type) { case CollisionObjectType.ColSphere: shape = new CollisionSphere(cp, cd.x); break; case CollisionObjectType.ColCylinder: // We treat it as a capsule, but we raise the // capsule up by the capRadius, and shorten // the segment by the double the capRadius Vector3 top = cp; top.y += cd.y - cd.x * 2f; cp.y += cd.x; shape = new CollisionCapsule(cp, top, cd.x); break; case CollisionObjectType.ColBox: Vector3 tp = cp; tp.x -= cd.x * .5f; tp.y -= cd.y * .5f; shape = new CollisionAABB(tp, tp + cd); break; } collisionAPI.AddCollisionShape(shape, handle); tiles[tX, tZ]++; objectsAdded++; if (MO.DoLog) { MO.Log(string.Format(" tiles[{0},{1}] = {2}, tile at [{3},{4}] after adding shape {5}", tX, tZ, tiles[tX, tZ], tileX, tileZ, shape.ToString())); } } } }
public Teams(TwitchAPI api) { v3 = new V3(api); v5 = new V5(api); }
public Games(TwitchAPI api) { v3 = new V3(api); v5 = new V5(api); helix = new Helix(api); }
/// <summary> /// 将三角形的三个点依次平移 /// </summary> /// <param name="translation"></param> /// <returns></returns> public Triangle Translate(Vector3d translation) { return(new Triangle(V1.Move(translation), V2.Move(translation), V3.Move(translation))); }
/// <summary> /// Updates the P, UV and Normal properties for either floor or ceiling. /// Fills in current 3D data for the subsector vertices. /// Note: Z component is the height here. /// </summary> /// <param name="IsFloor">Whether to create for floor or ceiling</param> /// <param name="Scale">Optional additional scale to apply.</param> public void UpdateVertexData(bool IsFloor, Real Scale = 1.0f) { const Real INV64 = 1.0f / (Real)(64 << 4); // from old code.. V3 normal; V3[] p = new V3[Vertices.Count]; V2[] uv = new V2[Vertices.Count]; Real left = 0; Real top = 0; Real oneOverC = 0.0f; RooSectorSlopeInfo slopeInfo = (IsFloor) ? Sector.SlopeInfoFloor : Sector.SlopeInfoCeiling; /*****************************************************************/ // find most top left vertex and get its coordinates if (slopeInfo != null) { left = (int)slopeInfo.X0; top = (int)slopeInfo.Y0; oneOverC = 1.0f / slopeInfo.C; } else { for (int i = 0; i < Vertices.Count; i++) { if (Vertices[i].X < left) { left = Vertices[i].X; } if (Vertices[i].Y < top) { top = Vertices[i].Y; } } } /*****************************************************************/ for (int count = 0; count < Vertices.Count; count++) { // 1: Fill in vertex coordinates if (slopeInfo != null) { p[count].X = Vertices[count].X; p[count].Y = Vertices[count].Y; p[count].Z = (-slopeInfo.A * p[count].X - slopeInfo.B * p[count].Y - slopeInfo.D) * oneOverC; } else { p[count].X = Vertices[count].X; p[count].Y = Vertices[count].Y; p[count].Z = (IsFloor) ? (Sector.FloorHeight * 16.0f) : (Sector.CeilingHeight * 16.0f); } // 2.1: UV with slope if (slopeInfo != null) { V3 intersectTop; V3 intersectLeft; V3 vectorU; V3 vectorV; V3 vector; Real distance; Real U, temp; // calc distance from top line (vector u) U = ((p[count].X - slopeInfo.P0.X) * (slopeInfo.P1.X - slopeInfo.P0.X)) + ((p[count].Z - slopeInfo.P0.Z) * (slopeInfo.P1.Z - slopeInfo.P0.Z)) + ((p[count].Y - slopeInfo.P0.Y) * (slopeInfo.P1.Y - slopeInfo.P0.Y)); temp = ((slopeInfo.P1.X - slopeInfo.P0.X) * (slopeInfo.P1.X - slopeInfo.P0.X)) + ((slopeInfo.P1.Z - slopeInfo.P0.Z) * (slopeInfo.P1.Z - slopeInfo.P0.Z)) + ((slopeInfo.P1.Y - slopeInfo.P0.Y) * (slopeInfo.P1.Y - slopeInfo.P0.Y)); if (temp == 0.0f) { temp = 1.0f; } U /= temp; intersectTop.X = slopeInfo.P0.X + U * (slopeInfo.P1.X - slopeInfo.P0.X); intersectTop.Z = slopeInfo.P0.Z + U * (slopeInfo.P1.Z - slopeInfo.P0.Z); intersectTop.Y = slopeInfo.P0.Y + U * (slopeInfo.P1.Y - slopeInfo.P0.Y); uv[count].X = (Real)System.Math.Sqrt( (p[count].X - intersectTop.X) * (p[count].X - intersectTop.X) + (p[count].Z - intersectTop.Z) * (p[count].Z - intersectTop.Z) + (p[count].Y - intersectTop.Y) * (p[count].Y - intersectTop.Y)); // calc distance from left line (vector v) U = ((p[count].X - slopeInfo.P0.X) * (slopeInfo.P2.X - slopeInfo.P0.X)) + ((p[count].Z - slopeInfo.P0.Z) * (slopeInfo.P2.Z - slopeInfo.P0.Z)) + ((p[count].Y - slopeInfo.P0.Y) * (slopeInfo.P2.Y - slopeInfo.P0.Y)); temp = ((slopeInfo.P2.X - slopeInfo.P0.X) * (slopeInfo.P2.X - slopeInfo.P0.X)) + ((slopeInfo.P2.Z - slopeInfo.P0.Z) * (slopeInfo.P2.Z - slopeInfo.P0.Z)) + ((slopeInfo.P2.Y - slopeInfo.P0.Y) * (slopeInfo.P2.Y - slopeInfo.P0.Y)); if (temp == 0.0f) { temp = 1.0f; } U /= temp; intersectLeft.X = slopeInfo.P0.X + U * (slopeInfo.P2.X - slopeInfo.P0.X); intersectLeft.Z = slopeInfo.P0.Z + U * (slopeInfo.P2.Z - slopeInfo.P0.Z); intersectLeft.Y = slopeInfo.P0.Y + U * (slopeInfo.P2.Y - slopeInfo.P0.Y); uv[count].Y = (Real)System.Math.Sqrt( (p[count].X - intersectLeft.X) * (p[count].X - intersectLeft.X) + (p[count].Z - intersectLeft.Z) * (p[count].Z - intersectLeft.Z) + (p[count].Y - intersectLeft.Y) * (p[count].Y - intersectLeft.Y)); uv[count].X += (Sector.TextureY << 4) / 2.0f; uv[count].Y += (Sector.TextureX << 4) / 2.0f; vectorU.X = slopeInfo.P1.X - slopeInfo.P0.X; vectorU.Z = slopeInfo.P1.Z - slopeInfo.P0.Z; vectorU.Y = slopeInfo.P1.Y - slopeInfo.P0.Y; distance = (Real)System.Math.Sqrt((vectorU.X * vectorU.X) + (vectorU.Y * vectorU.Y)); if (distance == 0.0f) { distance = 1.0f; } vectorU.X /= distance; vectorU.Z /= distance; vectorU.Y /= distance; vectorV.X = slopeInfo.P2.X - slopeInfo.P0.X; vectorV.Z = slopeInfo.P2.Z - slopeInfo.P0.Z; vectorV.Y = slopeInfo.P2.Y - slopeInfo.P0.Y; distance = (Real)System.Math.Sqrt((vectorV.X * vectorV.X) + (vectorV.Y * vectorV.Y)); if (distance == 0.0f) { distance = 1.0f; } vectorV.X /= distance; vectorV.Z /= distance; vectorV.Y /= distance; vector.X = p[count].X - slopeInfo.P0.X; vector.Y = p[count].Y - slopeInfo.P0.Y; distance = (Real)System.Math.Sqrt((vector.X * vector.X) + (vector.Y * vector.Y)); if (distance == 0) { distance = 1.0f; } vector.X /= distance; vector.Y /= distance; if (((vector.X * vectorU.X) + (vector.Y * vectorU.Y)) <= 0) { uv[count].Y = -uv[count].Y; } if (((vector.X * vectorV.X) + (vector.Y * vectorV.Y)) > 0) { uv[count].X = -uv[count].X; } } // 2.2: UV without slope else { uv[count].X = System.Math.Abs(Vertices[count].Y - top) - (Sector.TextureY << 4); uv[count].Y = System.Math.Abs(Vertices[count].X - left) - (Sector.TextureX << 4); } uv[count].X *= INV64; uv[count].Y *= INV64; // apply additional userscale p[count] *= Scale; } /*****************************************************************/ // Calculate the normal if (slopeInfo != null) { // if the sector is sloped, we get the normal from slopeinfo normal.X = slopeInfo.A; normal.Y = slopeInfo.B; normal.Z = slopeInfo.C; normal.Normalize(); } else if (IsFloor) { // default normal for non sloped floor normal.X = 0.0f; normal.Y = 0.0f; normal.Z = 1.0f; } else { // default normal for non sloped ceilings normal.X = 0.0f; normal.Y = 0.0f; normal.Z = -1.0f; } /*****************************************************************/ // save in class properties depending on floor/ceiling if (IsFloor) { FloorP = p; FloorUV = uv; FloorNormal = normal; } else { CeilingP = p; CeilingUV = uv; CeilingNormal = normal; } }
public Search(TwitchAPI api) { v3 = new V3(api); v5 = new V5(api); }
public ChannelFeeds(TwitchAPI api) { v3 = new V3(api); v5 = new V5(api); }
private bool Set(V3 pScreen) { return Set((int) pScreen.X, (int) pScreen.Y, pScreen.Z); }
public void setDirection(V3 direction) { this.direction = direction; }
public static V3 GetNormalized(this V3 v) { v.Normalize(); return(v); }
public DirectionalLight(V3 p_direction, Couleur p_couleur) : base(p_couleur) { this.direction = p_direction; }
public override V3 Normal(V3 p) { return Normal(); }
public override Couleur applyLight(Object3D enlightmentObject, V3 positionOnScene, V3 normal, Couleur color_surface) { foreach (Object3D one in RenderSing.getCurrentRender().getObject()) { V3 dirN = new V3(direction); dirN.Normalize(); double t = 0; if (enlightmentObject != one && one.testColition(positionOnScene, dirN, out t)) { return(new Couleur(0f, 0f, 0f)); } } return(this.diffuse(enlightmentObject, normal, color_surface) + this.specular(enlightmentObject, normal, color_surface)); }
public static V3 Cross( V3 a, V3 b ) { V3 v = new V3(a.Y * b.Z - b.Y * a.Z, a.Z * b.X - b.Z * a.X, a.X * b.Y - b.X * a.Y); return v; }
///<summary>transform.localEulerAngles-н x, z-г өөрчилнө</summary> public static void TleXz(this GameObject a, float x, float z) { a.transform.localEulerAngles = V3.Xz(a.transform.localEulerAngles, x, z); }
/// Retrieves uv values in the [0;1] range for a point p on the sphere. public override V2 UV(V3 p) { V3 d = p - Center; // cos(u) = (x - c.x) / (r * cos(v)) // sin(u) = (y - c.y) / (r * cos(v)) // tan(u) = sin(u) / cos(u) // u = atan((y - c.y) / (x - c.x)) float u = Mathf.Atan2(d.Y, d.X); // v = asin((z - c.z) / r) float v = Mathf.Asin(d.Z / Radius); // u,v in [0;1] u = (u / (2 * Mathf.PI)); v = 0.5f + (v / Mathf.PI); return new V2(u,v); }
/// Computes the ambient component of the Phong reflection model for /// an ambient light. public override Color ComputeAmbientLight( AmbientLight aL, Object3D obj, V3 p, V2 uv ) { return obj.TextureColor(uv) * aL.Intensity * obj.Material.KAmbient; }
public Subscriptions(TwitchAPI api) { v3 = new V3(api); }
public Chat(TwitchAPI api) { v3 = new V3(api); v5 = new V5(api); }
public PhongIllumination(V3 cameraPos) { CameraPos = cameraPos; }
public Raycasting(Canvas canvas, Scene scene, V3 cameraPos) : base(canvas, scene, cameraPos) { }
///<summary>transform.localEulerAngles-н x, y-г өөрчилнө</summary> public static void TleXy(this GameObject a, float x, float y) { a.transform.localEulerAngles = V3.Xy(a.transform.localEulerAngles, x, y); }
public string IsError() { if (string.IsNullOrWhiteSpace(GrsName)) { return("Укажите наименование ГРС"); } if (string.IsNullOrWhiteSpace(SubGrsName)) { return("Укажите наименование замерной нитки"); } if (Psantimeter > 0) { if (V1 + V2 + V3 + V9 + V10 + V11 > 0) { CalculateSmallK(); } else { K = SmallKConstants.KAll; } } else { if (V1 != 0 && !V1.CheckIntervalParams(90m, 97.9m)) { return("V1 параметр \"Объёмная концентрация метана\" несоответсвует"); } if (V2 != 0 && !V2.CheckIntervalParams(0.75m, 4.75m)) { return("V2 параметр \"Объёмная концентрация этана\" несоответсвует"); } if (V3 != 0 && !V3.CheckIntervalParams(0.30m, 3.5m)) { return("V3 параметр \"Объёмная концентрация пропана\" несоответсвует"); } if (V4 != 0 && !V4.CheckIntervalParams(0.01m, 0.5m)) { return("V4 параметр \"Объёмная концентрация i-бутана\" несоответсвует"); } if (!V5.CheckIntervalParams(0m, 0.4m)) { return("V5 параметр \"Объёмная концентрация n-бутана\" несоответсвует"); } if (!V6.CheckIntervalParams(0m, 0.2m)) { return("V6 параметр \"Объёмная концентрация i-пентана\" несоответсвует"); } if (!V7.CheckIntervalParams(0m, 0.15m)) { return("V7 параметр \"Объёмная концентрация n-пентана\" несоответсвует"); } if (!V8.CheckIntervalParams(0m, 0.3m)) { return("V8 параметр \"Объёмная концентрация гексана\" несоответсвует"); } if (V9 != 0 && !V9.CheckIntervalParams(0.1m, 2.5m)) { return("V9 параметр \"Объёмная концентрация углекислого газа\" несоответсвует"); } if (V10 != 0 && !V10.CheckIntervalParams(0.2m, 1.3m)) { return("V10 параметр \"Объёмная концентрация азота\" несоответсвует"); } if (!V11.CheckIntervalParams(0m, 0.3m)) { return("V11 параметр \"Объёмная концентрация кислорода\" несоответсвует"); } if (K == 0) { CalculateSmallK(); } else if (!K.CheckIntervalParams(1.24m, 2.1m)) { return("k параметр \"Объёмный показатель адиабаты\" несоответсвует"); } else { this.IsCalculateK = false; } } if (Z == 0) { this.Z = 0.882m; } else if (!Z.CheckIntervalParams(0.6m, 0.9999m)) { return("z параметр \"Коэффициент сжимаемости\" несоответсвует"); } if (!Pvxod.CheckIntervalParams(0.01m, 6m)) { return("Pвх параметр \"Давление газа на входе в ДГА\" несоответсвует"); } if (!Pvixod.CheckIntervalParams(0.01m, 4m)) { return("Pвых параметр \"Давление газа на выходе из ДГА\" несоответсвует"); } if (!Q.CheckIntervalParams(100m, 100000000m)) { return("Q параметр \"Расход газа по нитке\" несоответсвует"); } if (!Temperature.CheckIntervalParams(10m, 90m)) { return("t параметр \"Температура\" несоответсвует"); } if ((Nnominal > 0 && EffectProcent == 0) || (Nnominal == 0 && EffectProcent > 0)) { return("Укажите Nnominal и Procent, чтобы узнать эффективность расчета"); } CalculateParams(); return(string.Empty); }
/// Recursivly raytrace to get the color resulting from the refracted /// light component for the specified collisionPoint. private Color RefractionColor( V3 incidentVec, V3 collisionPoint, V2 collisionUV, Object3D collidedObj, int depth ) { if (!collidedObj.Material.IsTransparent()) { return Color.Black; } V3 normal = collidedObj.Normal(collisionPoint, collisionUV); Ray refractionRay = new Ray( origin: collisionPoint, direction: incidentVec.RefractedVector( normalVec: normal, n1: Scene.RefractiveIndex, n2: collidedObj.Material.RefractiveIndex ), originObject: null ); Color refractionColor = Raytrace(refractionRay, depth - 1); if (refractionColor == null) { return Color.Black; } return collidedObj.Material.Transparency * refractionColor; }
///<summary>transform.position-н y, z-г өөрчилнө</summary> public static void TpYz(this GameObject a, float y, float z) { a.transform.position = V3.Yz(a.transform.position, y, z); }
private Color ComputeSpecular( Light l, V3 reflectedVec, V3 viewingVec, Object3D obj, V2 uv ) { Color specularIllu = new Color(0, 0, 0); if (reflectedVec * viewingVec > 0.0f) { specularIllu = l.Intensity * obj.Material.KSpecular * Mathf.Pow( reflectedVec * viewingVec, obj.Material.Shininess ); } return specularIllu; }
///<summary>transform.localEulerAngles-н y, z-г өөрчилнө</summary> public static void TleYz(this GameObject a, float y, float z) { a.transform.localEulerAngles = V3.Yz(a.transform.localEulerAngles, y, z); }
/// Recursivly raytrace to get the color resulting from the reflected /// light component for the specified collisionPoint. private Color ReflectionColor( V3 incidentVec, V3 collisionPoint, V2 collisionUV, Object3D collidedObj, int depth ) { if (!collidedObj.Material.IsReflective()) { return Color.Black; } V3 normal = collidedObj.Normal(collisionPoint, collisionUV); Ray reflectionRay = new Ray( origin: collisionPoint, direction: incidentVec.ReflectedVector(normal), originObject: collidedObj ); Color reflectionColor = Raytrace(reflectionRay, depth - 1); if (reflectionColor == null) { return Color.Black; } return collidedObj.Material.Reflection * reflectionColor; }
///<summary>mesh-р эргэлтийн бие үүсгэнэ</summary> public static void RotModel(ref Mesh mesh, bool isFill, bool isDisUv, int n, List <Vector2> points, Tf tf) { List <Vector2> lis = new List <Vector2>(points); if (isFill) { lis.Insert(0, V2.X(points[0], 0)); lis.Add(V2.X(points[points.Count - 1], 0)); } // vertices Vector3[] vs = new Vector3[n * lis.Count]; float dAng = 360f / n; for (int i = 0; i < lis.Count; i++) { for (int j = 0; j < n; j++) { vs[i * n + j] = Tf.Rot(tf.r, V3.Mul(new Vector3(lis[i].x * M.Cos(j * dAng), lis[i].y, lis[i].x * M.Sin(j * dAng)), tf.s)) + tf.t; } } // triangles int[] ts = new int[n * 6 * (lis.Count - 1)]; for (int i = 0; i < lis.Count - 1; i++) { for (int j = 0; j < n; j++) { for (int k = 0; k < 6; k++) { ts[n * 6 * i + j * 6 + k] = n * i + (j + UvUArr[k]) % n + UvVArr[k] * n; } } } // uv Vector3[] v = new Vector3[ts.Length]; int[] t = new int[ts.Length]; Vector2[] uv = new Vector2[ts.Length]; float du = 1f / n, dv = 1f / (lis.Count - 1); if (isDisUv) { float dis = 0, tmpDis, curDis = 0; List <float> disLis = new List <float>(); for (int i = 1; i < lis.Count; i++) { tmpDis = Vector3.Distance(lis[i - 1], lis[i]); disLis.Add(tmpDis); dis += tmpDis; } for (int i = 0; i < ts.Length; i++) { v[i] = vs[ts[i]]; t[i] = i; uv[i] = new Vector2( (i / 6 % n + UvUArr[i % 6]) * du, (curDis + UvVArr[i % 6] * disLis[i / 6 / n]) / dis ); if ((i + 1) % (6 * n) == 0) { curDis += disLis[i / 6 / n]; } } } else { for (int i = 0; i < ts.Length; i++) { v[i] = vs[ts[i]]; t[i] = i; uv[i] = new Vector2( (i / 6 % n + UvUArr[i % 6]) * du, (i / 6 / n + UvVArr[i % 6]) * dv ); } } // mesh VsTsUvRn(ref mesh, vs, ts, uv); }