/// <summary> /// The rotate trackball. /// </summary> /// <param name="p1"> /// The previous mouse position. /// </param> /// <param name="p2"> /// The current mouse position. /// </param> /// <param name="rotateAround"> /// The point to rotate around. /// </param> private void RotateTrackball(Vector2 p1, Vector2 p2, Vector3 rotateAround) { // http://viewport3d.com/trackball.htm // http://www.codeplex.com/3DTools/Thread/View.aspx?ThreadId=22310 var v1 = ProjectToTrackball(p1, this.Viewport.ActualWidth, this.Viewport.ActualHeight); var v2 = ProjectToTrackball(p2, this.Viewport.ActualWidth, this.Viewport.ActualHeight); var cUP = Camera.CameraInternal.UpDirection; // transform the trackball coordinates to view space var viewZ = Vector3.Normalize(Camera.CameraInternal.LookDirection * Inv); var viewX = Vector3.Normalize(Vector3.Cross(cUP, viewZ) * Inv); var viewY = Vector3.Normalize(Vector3.Cross(viewX, viewZ)); var u1 = (viewZ * v1.Z) + (viewX * v1.X) + (viewY * v1.Y); var u2 = (viewZ * v2.Z) + (viewX * v2.X) + (viewY * v2.Y); // Could also use the Camera ViewMatrix // var vm = Viewport3DHelper.GetViewMatrix(this.ActualCamera); // vm.Invert(); // var ct = new MatrixTransform3D(vm); // var u1 = ct.Transform(v1); // var u2 = ct.Transform(v2); // Find the rotation axis and angle var axis = Vector3.Cross(u1, u2); if (axis.LengthSquared() < 1e-8) { return; } var angle = VectorExtensions.AngleBetween(u1, u2); // Create the transform var rotate = Matrix.RotationAxis(Vector3.Normalize(axis), -angle * (float)RotationSensitivity * 5); // Find vectors relative to the rotate-around point var relativeTarget = rotateAround - this.Camera.CameraInternal.Target; var relativePosition = rotateAround - this.Camera.CameraInternal.Position; // Rotate the relative vectors var newRelativeTarget = Vector3.TransformCoordinate(relativeTarget, rotate); var newRelativePosition = Vector3.TransformCoordinate(relativePosition, rotate); var newUpDirection = Vector3.TransformCoordinate(cUP, rotate); // Find new camera position var newTarget = rotateAround - newRelativeTarget; var newPosition = rotateAround - newRelativePosition; this.Camera.LookDirection = (newTarget - newPosition).ToVector3D(); if (this.CameraMode == CameraMode.Inspect) { this.Camera.Position = newPosition.ToPoint3D(); } this.Camera.UpDirection = newUpDirection.ToVector3D(); }
private void Timer_Tick() { double angle = (0.05f * frame) * Math.PI / 180; var xAxis = new Vector3(1, 0, 0); var zAxis = new Vector3(0, 0, 1); var yAxis = new Vector3(0, 1, 0); var rotation = Matrix.RotationAxis(xAxis, 0); double angleEach = 0; int counter = 0; for (int i = 0; i < NumSegments && i < numBonesInModel; ++i, counter += numSegmentPerBone) { if (i == 0) { boneInternal[0] = rotation; } else { var vp = Vector3.Transform(path[counter - numSegmentPerBone], Matrix.RotationAxis(xAxis, (float)angleEach)).ToVector3(); angleEach += angle; var v = Vector3.Transform(path[counter], Matrix.RotationAxis(xAxis, (float)angleEach)).ToVector3(); var rad = Math.Acos(Vector3.Dot(yAxis, (v - vp).Normalized())); if (angleEach < 0) { rad = -rad; } var rot = Matrix.RotationAxis(xAxis, (float)rad); var trans = Matrix.Translation(v); boneInternal[i] = rot * trans; } } var newBone = new BoneMatricesStruct() { Bones = boneInternal.ToArray() }; context.Post((o) => { Bones = newBone; }, null); if (frame > 40 || frame < -40) { direction = !direction; } if (direction) { ++frame; } else { --frame; } }
private void LoadFile() { loader = new CMOReader(); var obj3Ds = loader.Read("Sphere_Bot_test.cmo"); foreach (var group in loader.AnimationHierarchy) { var boneGroup = new BoneGroupModel3D(); var skeletonGroup = new BoneGroupModel3D(); foreach (var obj3D in group.Meshes) { if (obj3D.Geometry is BoneSkinnedMeshGeometry3D boneMesh) { var model = new BoneSkinMeshGeometryModel3D() { Geometry = obj3D.Geometry, FrontCounterClockwise = false, CullMode = CullMode.Back, Material = obj3D.Material.ConvertToMaterial(), IsThrowingShadow = true }; boneGroup.Children.Add(model); } else if (obj3D.Geometry is MeshGeometry3D) { Models.Add(new MeshGeometryModel3D() { Geometry = obj3D.Geometry, CullMode = CullMode.Back, FrontCounterClockwise = false }); } } var skeletonModel = new BoneSkinMeshGeometryModel3D() { Geometry = BoneSkinnedMeshGeometry3D.CreateSkeletonMesh(group.Bones, 0.1f), CullMode = CullMode.Back, Material = BoneMaterial, PostEffects = "xray" }; skeletonGroup.Children.Add(skeletonModel); Models.Add(boneGroup); BoneModels.Add(skeletonGroup); BoneGroupsDictionary.Add(group.GUID, new List <BoneGroupModel3D>() { boneGroup, skeletonGroup }); } var diffuse = new MemoryStream(); using (var file = File.OpenRead(@"Sphere_Bot_Rusty_UVMap_color.png")) { file.CopyTo(diffuse); } var normal = new MemoryStream(); using (var file = File.OpenRead(@"Sphere_Bot_Rusty_UVMap_nmap.png")) { file.CopyTo(normal); } foreach (var group in Models) { if (group is GroupElement3D g) { foreach (var subModel in g.Children) { if (subModel is MaterialGeometryModel3D model) { var m = model.Material as PhongMaterial; m.EmissiveColor = Colors.Black.ToColor4(); m.DiffuseMap = diffuse; m.NormalMap = normal; m.RenderShadowMap = true; } } } } Animations = loader.UniqueAnimations.Keys.ToArray(); ModelTransform = new Media3D.MatrixTransform3D((Matrix.Scaling(10, 10, 10) * Matrix.RotationAxis(Vector3.UnitX, -(float)Math.PI / 2)).ToMatrix3D()); foreach (var group in loader.AnimationHierarchy) { foreach (var ani in group.Animations) { if (!keyframeUpdaters.ContainsKey(ani.Key)) { keyframeUpdaters.Add(ani.Key, new List <KeyValuePair <Guid, KeyFrameUpdater> >()); } keyframeUpdaters[ani.Key].Add(new KeyValuePair <Guid, KeyFrameUpdater>(group.GUID, new KeyFrameUpdater(ani.Value, group.Bones))); } } }