public override bool testColition(V3 positionStart, V3 direction, out double TPositionColition) { V3 normaleToTheRect = (this.largeur ^ this.longueur); normaleToTheRect.Normalize(); V3 eyesToPosition = this.getPosition() - positionStart; double t = (eyesToPosition * normaleToTheRect) / (direction * normaleToTheRect); if (t < 0) { TPositionColition = 0; return(false); } V3 ai = (float)t * direction + positionStart - this.getPosition(); double la = (this.largeur * ai) / (this.largeur * this.largeur); double lo = (this.longueur * ai) / (this.longueur * this.longueur); if (0 < lo && lo < 1 && 0 < la && la < 1) { TPositionColition = t; return(true); } TPositionColition = 0; return(false); }
public V3 Normal() { V3 normal = VA ^ VB; normal.Normalize(); return(normal); }
override public V3 Normal(V3 p) { V3 n = p - Center; n.Normalize(); return(n); }
public void UpdatePosition(long TickSpan, RooFile RooFile) { if (!isMoving) { return; } // source->destination delta vector and squared distance (in 3D) V3 dvector = targetObject.Position3D - position3D; Real distance2 = dvector.LengthSquared; // end not yet reached? if (distance2 > EPSILON2) { if (Speed != (byte)MovementSpeed.Teleport) { // normalise to get plain direction dvector.Normalize(); // process another step based on time delta V3 step = dvector * (Real)speed * (Real)TickSpan * GeometryConstants.PROJECTILEMOVEBASECOEFF; // check if this step is greater than distance left if (step.LengthSquared > distance2) { // directly update for teleport-speed zero position3D.X = TargetObject.Position3D.X; position3D.Y = TargetObject.Position3D.Y; position3D.Z = TargetObject.Position3D.Z; // movement finished IsMoving = false; } else { // do the step position3D.X += step.X; position3D.Y += step.Y; position3D.Z += step.Z; } } else { // directly update for teleport-speed zero position3D.X = TargetObject.Position3D.X; position3D.Y = TargetObject.Position3D.Y; position3D.Z = TargetObject.Position3D.Z; } // trigger changed event RaisePropertyChanged(new PropertyChangedEventArgs(PROPNAME_POSITION3D)); } else { IsMoving = false; } }
/// Computes the diffuse and specular components of the Phong /// reflection model for a point light. override public 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); }
public Ray(V3 origin, V3 direction, Object3D originObject = null) { Origin = origin; Direction = direction; Direction.Normalize(); OriginObject = originObject; Distance = float.MaxValue; }
override public 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)); }
public override Couleur drawPixel(V3 position) { V3 ai = position - this.getPosition(); double la = (this.largeur * ai) / (this.largeur * this.largeur); double lo = (this.longueur * ai) / (this.longueur * this.longueur); V3 vectRect = ((float)la * this.largeur) + ((float)lo * this.longueur); V3 copyVectRect = new V3(vectRect); copyVectRect.Normalize(); float dhsdu; float dhsdv; this.getBump(la, lo, out dhsdu, out dhsdv); V3 dmsdu = new V3((float)(-1 * Math.Cos(lo) * Math.Sin(la)), (float)(1 * Math.Cos(lo) * Math.Cos(la)), 0.0f); V3 dmsdv = new V3((float)(-1 * Math.Sin(lo) * Math.Cos(la)), (float)(-1 * Math.Sin(lo) * Math.Sin(la)), (float)(1 * Math.Cos(lo))); V3 dmpsdu = dmsdu + dhsdu * copyVectRect; V3 dmpsdv = dmsdv + dhsdv * copyVectRect; V3 Np = ((dmpsdu ^ dmpsdv) / (dmpsdu ^ dmpsdv).Norm()); V3 vecteurBump = Np; V3 position_point = this.getPosition() + vectRect; Couleur vcolor = new Couleur(); foreach (Light light in RenderSing.getCurrentRender().getLight()) { vcolor += light.applyLight(this, position_point, vecteurBump, this.getColor(la, lo)); } return(vcolor); }
public Couleur specular(Object3D b, V3 v, Couleur color_surface) { V3 copy_v = new V3(v); copy_v.Normalize(); V3 copy_pos = new V3(this.direction); copy_pos.Normalize(); float sca = (copy_pos * copy_v); V3 v_curent_perfect = (copy_v * sca * 2.0f) - copy_pos; V3 v_current_oeil = -(v + b.getPosition()) + RenderSing.getCurrentRender().getEyesPosition(); float a = (float)Math.Pow((Math.Max((v_curent_perfect * v_current_oeil) / (v_curent_perfect.Norm() * v_current_oeil.Norm()), 0)), 25); return(this.couleur * a); }
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)); }
/// Returns this object's normal altered by the Bump Map attached to /// this object's material. protected V3 AlteredNormal(V3 p, V2 uv) { V2 dh = Material.BumpMap.Bump(uv); Tuple <V3, V3> dP = DerivativePoint(uv); V3 dPdu = dP.Item1; V3 dPdv = dP.Item2; V3 n = Normal(p); V3 alteredN = n + Material.KBump * ( (dPdu ^ n * dh.V) + (n * dh.U ^ dPdv) ); alteredN.Normalize(); return(alteredN); }
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); }
override public 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); }
/// <summary> /// Updates FloorNormal and CeilingNormal properties. /// </summary> public void UpdateNormals() { if (Sector == null) { return; } // floor if (Sector.SlopeInfoFloor != null) { FloorNormal.X = Sector.SlopeInfoFloor.A; FloorNormal.Y = Sector.SlopeInfoFloor.B; FloorNormal.Z = Sector.SlopeInfoFloor.C; FloorNormal.Normalize(); } else { FloorNormal.X = 0.0f; FloorNormal.Y = 0.0f; FloorNormal.Z = 1.0f; } // ceiling if (Sector.SlopeInfoCeiling != null) { CeilingNormal.X = Sector.SlopeInfoCeiling.A; CeilingNormal.Y = Sector.SlopeInfoCeiling.B; CeilingNormal.Z = Sector.SlopeInfoCeiling.C; CeilingNormal.Normalize(); } else { CeilingNormal.X = 0.0f; CeilingNormal.Y = 0.0f; CeilingNormal.Z = -1.0f; } }
override public 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> /// Executes the provided XmlDocument on the PMX object. /// </summary> public static RunnerResult Execute(XmlDocument doc, IPXPmx pmx, IPXPmxBuilder builder, RunnerProgress progress) { XmlElement root = doc.DocumentElement; progress.Report(0, "> Execution started."); // Begin processing // Only the first level of elements are interpreted as commands. XmlElement[] commands = root.ChildNodes.OfType <XmlElement>().ToArray(); for (int i = 0; i < commands.Length; ++i) { try { XmlElement node = commands[i]; // The meaningful content of each case constitutes a separate block to avoid mixing variables. Might be unnecessary, but right now I'm not feeling too hot and my output WILL be sloppy. // Should review this code later. switch (node.Name.ToLowerInvariant()) { // Creates a new bone with the provided properties. case "bone": { string name = Math.Abs(Guid.NewGuid().GetHashCode()).ToString(); IPXBone bone = null; // Get name and check for collision if (node["name"] != null) { name = node["name"].InnerText; IPXBone existing = pmx.Bone.Where(b => b.Name == name).FirstOrDefault(); if (existing != null) { // If there is a collision, refer to the collision attribute switch (node["name"].GetAttribute("collision")) { // If the attribute is "update" or "replace", refer to the existing bone for the rest of the command. case "replace": case "update": bone = existing; break; // If the attribute is "skip", don't do anything with the bone and skip the command. case "skip": continue; // If the attribute is not valid, create a new bone and ignore the old one. default: bone = builder.Bone(); bone.Name = bone.NameE = name; break; } } else { bone = builder.Bone(); bone.Name = bone.NameE = name; } } else { bone = builder.Bone(); bone.Name = bone.NameE = name; } if (node["position"] != null) { bone.Position = node["position"].GetV3(); } if (node["translation"] != null) { bone.IsTranslation = bool.TryParse(node["translation"].InnerText, out bool translation) ? translation : false; } if (node["parent"] != null) { bone.Parent = Selector.Bone.Selector(node["parent"], pmx).FirstOrDefault(); } if (node["axis"] != null) { V3 v = node["axis"].GetV3(); v.Normalize(); bone.IsFixAxis = true; bone.FixAxis = v; } if (node["weight"] != null) { //IEnumerable<IPXVertex> vertices = Selector.Vertex.SelectorList(node["weight"].ChildNodes, pmx); IEnumerable <IPXVertex> vertices = Selector.Vertex.SelectorNode(node["weight"], pmx); foreach (IPXVertex v in vertices) { v.Bone1 = bone; v.Weight1 = 1; v.Bone2 = v.Bone3 = v.Bone4 = null; v.Weight2 = v.Weight3 = v.Weight4 = 0; } } pmx.Bone.Add(bone); progress.Report(Percent(i + 1, commands.Length), string.Format("[bone] Added new bone {0}.", bone.Name)); } break; // Assigns the selected vertices to the selected bone using BDEF1. case "weight": { IPXBone bone = null; if (node["target"] != null) { bone = Selector.Bone.Selector(node["target"], pmx).FirstOrDefault(); if (bone == null) { progress.Report(Percent(i + 1, commands.Length), string.Format("[weight] Bone was not found.", node["target"].InnerText)); break; } } else { progress.Report(Percent(i + 1, commands.Length), "[weight] Bone selector was not specified."); break; } // Set vertex weights if (node["select"] == null) { progress.Report(Percent(i + 1, commands.Length), "[weight] No vertices were selected."); break; } IEnumerable <IPXVertex> vertices = Selector.Vertex.SelectorNode(node["select"], pmx); foreach (IPXVertex v in vertices) { v.Bone1 = bone; v.Weight1 = 1; v.Bone2 = v.Bone3 = v.Bone4 = null; v.Weight2 = v.Weight3 = v.Weight4 = 0; } progress.Report(Percent(i + 1, commands.Length), string.Format("[weight] Weighted {0} vertices to {1} ({2}).", vertices.Count(), bone.Name, bone.NameE)); } break; // Creates a new UV morph. case "uvmorph": { // The morph's properties are defined in attributes. IPXMorph morph = builder.Morph(); morph.Kind = MorphKind.UV; // Set the UV channel if (int.TryParse(node.GetAttribute("channel"), out int ch)) { switch (ch) { case 1: morph.Kind = MorphKind.UVA1; break; case 2: morph.Kind = MorphKind.UVA2; break; case 3: morph.Kind = MorphKind.UVA3; break; case 4: morph.Kind = MorphKind.UVA4; break; default: morph.Kind = MorphKind.UV; break; } } // Set the group panel if (int.TryParse(node.GetAttribute("group"), out int group) && group <= 4 && group >= 0) { morph.Panel = group; } else { switch (node.GetAttribute("group").ToLowerInvariant()) { case "hidden": case "hide": case "none": case "0": morph.Panel = 0; break; case "eyebrow": case "eyebrows": case "1": morph.Panel = 1; break; case "eye": case "eyes": case "2": morph.Panel = 2; break; case "mouth": case "3": morph.Panel = 3; break; default: morph.Panel = 4; break; } } // Set the name, ignore collisions if (node.HasAttribute("name")) { morph.Name = morph.NameE = node.GetAttribute("name"); } else { morph.Name = morph.NameE = morph.GetHashCode().ToString(); } // Each morph contains one or more steps. Each step has its own selectors and transforms, which are applied independently. foreach (XmlElement step in node.ChildNodes.OfType <XmlElement>().Where(el => el.Name.ToLowerInvariant() == "step")) { // Skip steps that have no selectors if (step["select"] == null) { continue; } // Select vertices IEnumerable <IPXVertex> vertices = Selector.Vertex.SelectorNode(step["select"], pmx); foreach (XmlElement e in step) { switch (e.Name.ToLowerInvariant()) { case "pan": case "translate": { V2 v = e.GetV2(); foreach (IPXVertex vertex in vertices) { IPXUVMorphOffset offset = builder.UVMorphOffset(); offset.Vertex = vertex; offset.Offset = new V4(v.X, v.Y, 0, 0); morph.Offsets.Add(offset); } } break; case "rotate": // TODO: UV morph rotation case "scale": // TODO: UV morph scaling default: break; } } } pmx.Morph.Add(morph); progress.Report(Percent(i + 1, commands.Length), string.Format("[uvmorph] Created UV morph {0} with {1} offsets.", morph.Name, morph.Offsets.Count)); } break; // No particular functionality, testing only. case "test": { //foreach (IPXMorph morph in pmx.Morph.Where(m => m.Kind == MorphKind.UV)) //{ // foreach (IPXUVMorphOffset o in morph.Offsets) // { // _report(string.Format("{0:f2}, {1:f2}, {2:f2}, {3:f2}", o.Offset.X, o.Offset.Y, o.Offset.Z, o.Offset.W), -1); // } //} } break; // Sets up the selected vertices for use with AutoLuminous. case "autoluminous": { if (node["select"] == null) { progress.Report(Percent(i + 1, commands.Length), "[weight] No vertices were selected."); break; } IEnumerable <IPXVertex> vertices = Selector.Vertex.SelectorNode(node["select"], pmx); // Set required values. pmx.Header.UVACount = Math.Max(pmx.Header.UVACount, 3); // UV1 int texture = 0; int hsv = 0; float flashFrequency = 0; // UV2 V4 baseColor = new V4(0, 0, 0, 0); // UV3 float texSubtract = 0; float flashBias = 0; float push = 0; // Base emissive color if (node["color"] != null) { baseColor = node["color"].GetV4(); } // Base emissive power if (node["power"] != null) { baseColor.W = node["power"].GetSingle(); } if (node["texture"] != null) { int.TryParse(node["texture"].InnerText, System.Globalization.NumberStyles.Integer, System.Globalization.NumberFormatInfo.InvariantInfo, out texture); } if (node["colormode"] != null) { switch (node["colormode"].InnerText.ToLowerInvariant()) { case "hsv": hsv = 10; break; default: hsv = 0; break; } } if (node["flash"] != null) { float.TryParse(node["flash"].GetAttribute("bias"), System.Globalization.NumberStyles.Float, System.Globalization.NumberFormatInfo.InvariantInfo, out flashBias); flashFrequency = node["flash"].GetSingle(); } if (node["subtract"] != null) { texSubtract = node["subtract"].GetSingle(); } if (node["push"] != null) { push = node["push"].GetSingle(); } foreach (IPXVertex v in vertices) { v.UVA1.X = 0.2f; // Required value v.UVA1.Y = 0.7f; // Required value v.UVA1.Z = flashFrequency; v.UVA1.W = texture + hsv; v.UVA2 = baseColor; v.UVA3.X = texSubtract; v.UVA3.Y = flashBias; v.UVA3.Z = push; } } break; // Creates a vertex morph for AutoLuminous properties. case "almorph": { if (node["select"] == null) { progress.Report(Percent(i + 1, commands.Length), "[weight] No vertices were selected."); break; } HashSet <IPXVertex> vertices = new HashSet <IPXVertex>(Selector.Vertex.SelectorNode(node["select"], pmx)); V4 color = new V4(); if (node["color"] != null) { color = node["color"].GetV4(); } // TODO: Implement the rest of the AL properties in ALMorph IPXMorph morph = builder.Morph(); morph.Kind = MorphKind.UVA2; if (node.HasAttribute("name")) { morph.Name = morph.NameE = node.GetAttribute("name"); } else { morph.Name = morph.NameE = morph.GetHashCode().ToString(); } foreach (IPXVertex v in vertices) { // Set required values in case the vertex isn't already AL-enabled v.UVA1.X = 0.2f; v.UVA1.Y = 0.7f; // Create the offset morph.Offsets.Add(builder.UVMorphOffset(v, color)); } } break; // Sets environment variables. case "settings": { foreach (XmlElement child in node.ChildNodes.OfType <XmlElement>()) { switch (child.Name.ToLowerInvariant()) { case "exception": break; case "regex": bool regexCI = GlobalSettings.RegexCaseInsensitive; bool.TryParse(child.GetAttributeCI("caseinsensitive"), out regexCI); break; case "colortype": GlobalSettings.ColorIsFloat = child.InnerText.ToLowerInvariant() == "float"; break; default: break; } } } break; // Displays a MessageBox with the provided content. Optionally perform certain actions based on user input. case "mbox": case "messagebox": case "prompt": { if (int.TryParse(node.GetAttributeCI("skip"), out int skipNumber) && skipNumber > 0) { StringBuilder sb = new StringBuilder(string.Format("Would you like to skip the following {0} command(s)?\n", skipNumber)); for (int j = 1; j <= skipNumber; ++j) { sb.Append(commands[i + j].Name); } MessageBox.Show(sb.ToString(), "Prompt: skip", MessageBoxButtons.YesNo, MessageBoxIcon.Question); } else { MessageBox.Show(node.InnerText, "Message", MessageBoxButtons.OK, MessageBoxIcon.Information); } } break; // Prints a line in the console. case "echo": case "print": progress.Report(Percent(i + 1, commands.Length), node.InnerText); break; default: progress.Report(Percent(i + 1, commands.Length), "Skipping unknown command " + node.Name); break; } } catch (Exception ex) { if (GlobalSettings.Exception == GlobalSettings.ErrorHandling.Ask) { if (MessageBox.Show(string.Format("The following exception has occured:\n\n{0}\n\nWould you like to continue execution?", ex.ToString()), "Exception", System.Windows.Forms.MessageBoxButtons.YesNo, System.Windows.Forms.MessageBoxIcon.Error) == System.Windows.Forms.DialogResult.No) { return(RunnerResult.Fail); } } else if (GlobalSettings.Exception == GlobalSettings.ErrorHandling.Abort) { return(RunnerResult.Fail); } } } // If control has reached this point, the execution is considered successful. return(RunnerResult.Success); }
public static V3 GetNormalized(this V3 v) { v.Normalize(); return(v); }
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); }
public DirectionalLight(Color intensity, V3 direction) : base(intensity) { Direction = direction; Direction.Normalize(); }
// 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; } }