private static void writeBodyNode( Node node, StreamWriter writer, bool fill = false) { IPXBody body = (IPXBody)node.pmxElement; string shape = "ellipse"; Dictionary <BodyMode, string> styleDict = new Dictionary <BodyMode, string>() { { BodyMode.Static, "solid" }, { BodyMode.Dynamic, "dashed" }, { BodyMode.DynamicWithBone, "dotted" } }; string style = styleDict[body.Mode]; if (fill) { style += ",filled"; } int index = bodyIndexDict[body]; if (null == body.Bone) { writer.WriteLine(String.Format( "{0} [shape = {1}, label = \"{2:D}: {3}\", style = \"{4}\"];", node.id, shape, index, body.Name, style)); } else { int boneIndex = boneIndexDict[body.Bone]; writer.WriteLine(String.Format( "{0} [shape = {1}, label = \"{2:D}: {3}\\n[{5:D}: {6}]\", style = \"{4}\"];", node.id, shape, index, body.Name, style, boneIndex, body.Bone.Name)); } }
private static Node makeBodyNode(IPXBody body) { int index = bodyIndexDict[body]; string bodyID = "BODY_" + index.ToString(); return(new Node(bodyID, body)); }
// bone object -> body objects private static void makeBone2BodiesDict(IPXPmx pmx) { bone2bodies = new Bone2BodiesDict(); for (int i = 0; i < pmx.Body.Count; i++) { IPXBody body = pmx.Body[i]; if (null != body.Bone) { if (bone2bodies.ContainsKey(body.Bone)) { bone2bodies[body.Bone].Add(body); } else { bone2bodies[body.Bone] = new List <IPXBody> { body }; } } } }
public IPXImpulseMorphOffset ImpulseMorphOffset(IPXBody body, bool local, V3 velocity, V3 torque) { throw new NotImplementedException(); }
private void generateButton_Click(object sender, EventArgs e) { if (string.IsNullOrEmpty(namingText.Text)) { MessageBox.Show("The name cannot be empty!"); return; } switch (positionSelect.SelectedIndex) { case 0: if (lastPointVector.Value.Magnitude <= 0) { MessageBox.Show("The target vector cannot be zero!"); return; } break; case 1: if (linkNumber.Value < pointCount.Value) { MessageBox.Show("The number of links must not be less than the number of control points."); return; } break; default: break; } if (editPoints.Checked) { editPoints.Checked = false; } IPXPmx pmx = _args.Host.Connector.Pmx.GetCurrentState(); IPXBone parent = null; if (parentBoneSelect.SelectedIndex > 0) { parent = pmx.Bone[parentBoneSelect.SelectedIndex - 1]; } IPXBone[] chain = null; int count; Vector3 start; Vector3 delta; switch (positionSelect.SelectedIndex) { case 0: // From start through target start = firstPointVector.Value; delta = lastPointVector.Value.Normalized * (float)distanceNumber.Value; count = (int)Math.Round(linkNumber.Value); chain = Builder.GenerateChain(_args.Host.Builder.Pmx, Math.Max(count, 1), delta, start, namingText.Text, namingEnText.Text); break; case 1: // Segmented path count = (int)Math.Round(linkNumber.Value); chain = Builder.GenerateSegmentedChain(_args.Host.Builder.Pmx, count, _curvePoints, namingText.Text, namingEnText.Text); break; case 2: // Along a spline count = (int)Math.Round(linkNumber.Value); chain = Builder.GenerateSplineChain(_args.Host.Builder.Pmx, count, _curvePoints, namingText.Text, namingEnText.Text); break; case 3: // Along a spline with even distribution count = (int)Math.Round(linkNumber.Value); chain = Builder.GenerateSplineChainEvenSpaced(_args.Host.Builder.Pmx, count, _curvePoints, namingText.Text, namingEnText.Text); break; default: break; } if (chainTypeIK.Checked) { IPXBone handle = _args.Host.Builder.Pmx.Bone(); handle.Parent = parent; handle.Name = namingText.Text.Replace("#", "IK").Replace("&", "IK"); handle.NameE = namingEnText.Text.Replace("#", "IK").Replace("&", "IK"); handle.IsTranslation = true; handle.IsIK = true; IPXIK ik = handle.IK; for (int i = chain.Length - 2; i >= 0; --i) { ik.Links.Add(_args.Host.Builder.Pmx.IKLink(chain[i])); } ik.Target = chain[chain.Length - 1]; ik.Angle = (float)((20.0 / 180.0) * Math.PI); ik.LoopCount = 10; handle.Position = ik.Target.Position; pmx.Bone.Add(handle); } if (createPhysics.Checked) { IPXJoint pj = null; if (_physicsSettings.AttachToParent) { IPXBody pb = pmx.Body.Where(b => b.Bone == parent).FirstOrDefault(); if (pb == null) { MessageBox.Show("Could not attach physics chain to the parent bone because it doesn't have a rigidbody.", "Warning"); } else { pj = _args.Host.Builder.Pmx.Joint(); pj.Name = namingText.Text.Replace("#", "P").Replace("&", "P"); pj.NameE = namingEnText.Text.Replace("#", "P").Replace("&", "P"); pj.Position = pb.Bone.Position; pj.BodyA = pb; pmx.Joint.Add(pj); } } Builder.GeneratePhysics(_args.Host.Builder.Pmx, chain, _physicsSettings, out IPXBody[] rigidbodies, out IPXJoint[] joints);
// 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; } }