/// <summary> /// OSG utiliza una representacion 'row-mayor', OpenGL 'column-mayor' y Clip /// 'column-mayor'. /// http://steve.hollasch.net/cgindex/math/matrix/column-vec.html /// http://www.openscenegraph.org/projects/osg/wiki/Support/Maths/MatrixTransformations /// </summary> /// <param name="mat"></param> /// <returns></returns> public static Matrix4x4d ToMatrix4x4d(this Matrixd mat) { return(new Matrix4x4d(mat.get(0, 0), mat.get(1, 0), mat.get(2, 0), mat.get(3, 0), mat.get(0, 1), mat.get(1, 1), mat.get(2, 1), mat.get(3, 1), mat.get(0, 2), mat.get(1, 2), mat.get(2, 2), mat.get(3, 2), mat.get(0, 3), mat.get(1, 3), mat.get(2, 3), mat.get(3, 3))); }
private void DrawFlat(GraphicsDevice graphicsDevice, SectorBounds bounds, ISector rootSector) { RenderTarget2D renderTarget = renderTargets[rootSector]; // Set the render target graphicsDevice.SetRenderTarget(renderTarget); graphicsDevice.DepthStencilState = new DepthStencilState() { DepthBufferEnable = true }; graphicsDevice.Clear(Pallete.OCEAN_BLUE); double relativeCameraZoom = camera.cameraZoom - Math.Log(ZCoords.GetSectorManager().GetTopmostOSMSectors().Count, 4) + (Game1.RECORDING ? 1 : 0); int zoomLevel = Math.Min(Math.Max((int)(relativeCameraZoom - 3), 0), ZCoords.GetSectorManager().GetHighestOSMZoom()); List <ISector> containedSectors = rootSector.GetSectorsInRange(bounds.minX, bounds.maxX, bounds.minY, bounds.maxY, zoomLevel); List <ISector> sorted = containedSectors.Where(x => x.GetRoot().Equals(rootSector)).ToList(); sorted.Sort((x, y) => x.Zoom.CompareTo(y.Zoom)); foreach (var sector in sorted) { IGraphicsBuffer buffer = loadedMaps[sector]; if (!(buffer is ImageTileBuffer)) { continue; } Matrixd projection = Matrixd.CreateOrthographicOffCenter(bounds.minX * (1 << sector.Zoom) - sector.X, bounds.maxX * (1 << sector.Zoom) - sector.X, bounds.maxY * (1 << sector.Zoom) - sector.Y, bounds.minY * (1 << sector.Zoom) - sector.Y, -1, 0.01f); // TODO: why negative? RenderContext context = new RenderContext(graphicsDevice, projection, bounds.minX * (1 << sector.Zoom) - sector.X, bounds.maxX * (1 << sector.Zoom) - sector.X, bounds.minY * (1 << sector.Zoom) - sector.Y, bounds.maxY * (1 << sector.Zoom) - sector.Y, camera.cameraZoom, RenderContext.LayerPass.MAIN_PASS); buffer.Draw(context); } }
public Texture2D GetImage(GraphicsDevice graphicsDevice) { if (RENDER_BUFFER == null) { Vector2d topLeft = new Vector2d(0, 0); Vector2d bottomRight = new Vector2d(1, 1); Matrixd projection = Matrixd.CreateOrthographicOffCenter(0, 1, Math.Sqrt(0.5), 0, -2, 2); // TODO: why negative? //projection = Matrixd.CreateOrthographicOffCenter(0.1, 0.105, 0.1 + Math.Sqrt(0.5) * 0.005, 0.1, -2, 2); // TODO: why negative? Matrixd skew = Matrixd.CreateRotationX(Math.PI / 4); context = new RenderContext(graphicsDevice, skew * projection, topLeft.X, bottomRight.X, topLeft.Y, bottomRight.Y, 0, RenderContext.LayerPass.MAIN_PASS); context.highQuality = true; context.deferred = false; context.treeExtraPH = Math.Sqrt(0.5); // undo our stretching when measuring tree height (TODO: very hacky) context.treeLayer = MakeDefaultRenderTarget(graphicsDevice); context.grassLayer = MakeDefaultRenderTarget(graphicsDevice); RENDER_BUFFER = MakeDefaultRenderTarget(graphicsDevice); TREE_DENSITY_BUFFER = context.treeLayer; GRASS_DENSITY_BUFFER = context.grassLayer; } InitDraw(context); graphicsDevice.SetRenderTarget(TREE_DENSITY_BUFFER); context.layerPass = RenderContext.LayerPass.TREE_DENSITY_PASS; Draw(context); graphicsDevice.SetRenderTarget(GRASS_DENSITY_BUFFER); context.layerPass = RenderContext.LayerPass.GRASS_DENSITY_PASS; Draw(context); graphicsDevice.SetRenderTarget(RENDER_BUFFER); context.layerPass = RenderContext.LayerPass.MAIN_PASS; Draw(context); return(DownScale(graphicsDevice, RENDER_BUFFER, 512)); }
public override void Draw(RenderContext renderContext, GameTime gameTime) { if (renderContext.layerPass != RenderContext.LayerPass.MAIN_PASS) { return; } if (Game1.RECORDING) { MoveShip(renderContext.graphicsDevice); } SphereVector unitPosition = new SphereVector(position.Normalized()); SphereVector up = unitPosition.WalkNorth(Math.PI / 2); SphereVector right = new SphereVector(up.Cross(unitPosition).Normalized()); double rotation = Math.Atan2(forward.Dot(-right), forward.Dot(up)); // we want up to be 0 and a positive rotation to be cw Matrixd shipWVP = CreateShipWVP(renderContext, rotation); foreach (ModelMesh mesh in GlobalContent.StartingShuttle.Meshes) { foreach (BasicEffect eff in mesh.Effects) { eff.EnableDefaultLighting(); eff.World = shipWVP.toMatrix(); eff.VertexColorEnabled = false; eff.Alpha = 1; } mesh.Draw(); } }
// KalmanInitialized is called for initializing the initial estimate public void KalmanInitialized(Matrixd stateTransMatrix, Matrixd controlMatrix, Matrixd inputVar, Matrixd procNoiseVector, Matrixd obsvMatrix, Matrixd measNoiseVector) { // assign the variables if (stateTransMatrix.rows != Fd.rows || stateTransMatrix.columns != Fd.columns) { throw new ArgumentException("Can not assign the state transition matrix with different rows or columns.", nameof(stateTransMatrix)); } else { Fd = stateTransMatrix; } if (controlMatrix.rows != Gd.rows || controlMatrix.columns != Gd.columns) { throw new ArgumentException("Can not assign the control matrix with different rows or columns.", nameof(controlMatrix)); } else { Gd = controlMatrix; } if (inputVar.rows != ud.rows || inputVar.columns != ud.columns) { throw new ArgumentException("Can not assign the input variable with different rows or columns.", nameof(inputVar)); } else { ud = inputVar; } if (procNoiseVector.rows != wd.rows || procNoiseVector.columns != wd.columns) { throw new ArgumentException("Can not assign the process noise vector with different rows or columns.", nameof(procNoiseVector)); } else { wd = procNoiseVector; } if (obsvMatrix.rows != Hd.rows || obsvMatrix.columns != Hd.columns) { throw new ArgumentException("Can not assign the observation matrix with different rows or columns.", nameof(obsvMatrix)); } else { Hd = obsvMatrix; } if (measNoiseVector.rows != vd.rows || measNoiseVector.columns != vd.columns) { throw new ArgumentException("Can not assign the measurement noise vector with different rows or columns.", nameof(measNoiseVector)); } else { vd = measNoiseVector; } // construct the process noise uncertainty and measurement noise uncertainty Qd = Matrixd.Mul(wd, Matrixd.Transpose(wd)); Rd = Matrixd.Mul(vd, Matrixd.Transpose(vd)); // calculate the initial estimate(initial state vector and estimate uncertainty) for updating iteration KalmanPredictd(); }
public void Draw(RenderContext context) { double height = heightInFeet / 300000; RenderContext context2 = new RenderContext(context.graphicsDevice, Matrixd.CreateTranslation(new Vector3d(0, 0, height)) * context.WVP, context.minX, context.maxX, context.minY, context.maxY, context.cameraZoom, context.layerPass); buffer.Draw(context2, PrimitiveType.TriangleList, null, roofColor.ToVector3()); buffer2.Draw(context, PrimitiveType.TriangleList, wallTexture, null); }
internal Rayd CastFromCamera(GraphicsDevice graphicsDevice, Vector2 mouseVector) { Matrixd worldd = Matrixd.CreateRotationZ(-cameraRotX) * Matrixd.CreateRotationX(cameraRotY); double distance = 9 * Math.Pow(0.5, cameraZoom); Matrixd viewd = CameraMatrixManager.GetWorldViewd(distance); Matrixd projectiond = CameraMatrixManager.GetWorldProjectiond(distance, graphicsDevice.Viewport.AspectRatio); return(Rayd.CastFromCamera(graphicsDevice, mouseVector.X, mouseVector.Y, projectiond, viewd, worldd)); }
public RenderContext(GraphicsDevice graphicsDevice, Matrixd WVP, double minX, double maxX, double minY, double maxY, double cameraZoom, LayerPass layerPass) { this.graphicsDevice = graphicsDevice; this.WVP = WVP; this.minX = minX; this.maxX = maxX; this.minY = minY; this.maxY = maxY; this.cameraZoom = cameraZoom; this.layerPass = layerPass; }
public static Matrixd ToMatrixd(this ITransform2D transform) { if (transform is Transform2Identity) { return(Matrixd.identity()); } if (transform is Transform2Matrix) { return(((Transform2Matrix)transform).Matrix.ToMatrixd()); } throw new NotSupportedException(); }
// yup, it returns lat/long only in the range you'd expect internal Vector3d GetLatLongOfCoord(GraphicsDevice graphicsDevice, double x, double y) { Matrixd worldd = Matrixd.CreateRotationZ(-cameraRotX) * Matrixd.CreateRotationX(cameraRotY); double distance = 9 * Math.Pow(0.5, cameraZoom); Matrixd viewd = CameraMatrixManager.GetWorldViewd(distance); Matrixd projectiond = CameraMatrixManager.GetWorldProjectiond(distance, graphicsDevice.Viewport.AspectRatio); Rayd ray = Rayd.CastFromCamera(graphicsDevice, x, y, projectiond, viewd, worldd); Vector3d intersection = ray.IntersectionSphere(new Vector3d(0, 0, 0), 1); // angle 0 if (intersection == null) { return(null); } return(ToLatLong(intersection)); }
// KalmanCorrectd is called for correcting the predict of the pre-state(first update for every iteration) public void KalmanCorrectd(Matrixd measurement) { // update the output vector(measurement result) if (measurement.rows != zd.rows || measurement.columns != zd.columns) { throw new ArgumentException("Can not update the measurement with different rows or columns.", nameof(measurement)); } else { zd = measurement; } // compute the kalman gain and correct the discrete state and estimate uncertainty Kd = Matrixd.Mul(Matrixd.Mul(Pd, Matrixd.Transpose(Hd)), Matrixd.Inverse(Matrixd.Mul(Matrixd.Mul(Hd, Pd), Matrixd.Transpose(Hd)) + Rd)); xd = xd + Matrixd.Mul(Kd, (zd - Matrixd.Mul(Hd, xd))); Pd = Matrixd.Mul(Matrixd.Mul((Matrixd.Identity(xd.rows, xd.rows) - Matrixd.Mul(Kd, Hd)), Pd), Matrixd.Transpose(Matrixd.Identity(xd.rows, xd.rows) - Matrixd.Mul(Kd, Hd))) + Matrixd.Mul(Matrixd.Mul(Kd, Rd), Matrixd.Transpose(Kd)); }
private void DoComposite() { Rectangle screenRect = new Rectangle(0, 0, GraphicsDevice.Viewport.Width, GraphicsDevice.Viewport.Height); SpriteBatch spriteBatch = new SpriteBatch(GraphicsDevice); if (DEFERRED_RENDERING) { //GraphicsDevice.SetRenderTargets(Game1.RENDER_BUFFER); Matrixd projection = Matrixd.CreatePerspectiveFieldOfView(Math.PI / 4, GraphicsDevice.Viewport.AspectRatio, 0.5, 2); GlobalContent.SSAOShader.Parameters["PixelSize"].SetValue(new Vector2(1.0f / GraphicsDevice.Viewport.Width, 2.0f / GraphicsDevice.Viewport.Height)); //GlobalContent.SSAOShader.Parameters["Projection"].SetValue(projection.toMatrix()); //GlobalContent.SSAOShader.Parameters["InverseProjection"].SetValue(Matrixd.Invert(projection).toMatrix()); Vector4[] randomOffsets = new Vector4[32]; Random rand = new Random(12345); for (int i = 0; i < 32; i++) { randomOffsets[i] = new Vector4((float)rand.NextDouble() * 2 - 1, (float)rand.NextDouble() * 2 - 1, -(float)rand.NextDouble(), 0); randomOffsets[i].Normalize(); randomOffsets[i] = randomOffsets[i] * (float)rand.NextDouble(); } GlobalContent.SSAOShader.Parameters["offsets"].SetValue(randomOffsets); float distance = 9 * (float)Math.Pow(0.5, Game1.camera.cameraZoom); #if WINDOWS GlobalContent.SSAOShader.Parameters["AlbedoTexture"].SetValue(Game1.G_BUFFER[2].RenderTarget); GlobalContent.SSAOShader.Parameters["NormalTexture"].SetValue(Game1.G_BUFFER[1].RenderTarget); GlobalContent.SSAOShader.Parameters["PositionTexture"].SetValue(Game1.G_BUFFER[0].RenderTarget); #else GlobalContent.SSAOShader.Parameters["PNATexture"].SetValue(Game1.G_BUFFER[0].RenderTarget); #endif DrawSquare(GraphicsDevice, GlobalContent.SSAOShader); GraphicsDevice.SetRenderTarget(null); spriteBatch.Begin(); spriteBatch.Draw((Texture2D)Game1.RENDER_BUFFER[0].RenderTarget, screenRect, Color.White); spriteBatch.End(); } else { GraphicsDevice.SetRenderTarget(null); spriteBatch.Begin(); spriteBatch.Draw((Texture2D)Game1.RENDER_BUFFER[0].RenderTarget, screenRect, Color.White); spriteBatch.End(); } }
private Matrixd CreateShipWVP(RenderContext renderContext, double rotation) { double fakeScale = Math.Max(Math.Pow(2, 21 - camera.cameraZoom), 1); // make the ship bigger to account for depth buffer limitations Vector3d shipPos = position; // earth radius 6371 km double shipScale = fakeScale / 6371000; double distanceFromCamera = 30; // in meters Matrixd world = Matrixd.CreateRotationZ(-camera.cameraRotX) * Matrixd.CreateRotationX(camera.cameraRotY); // eh.... think hard on this later double distance = 9 * Math.Pow(0.5, camera.cameraZoom); shipPos += position.WalkNorth(-Math.PI / 4) * (distance * 2 - distanceFromCamera * shipScale); // why distance * 2?? Matrixd view = CameraMatrixManager.GetWorldViewd(distance); Matrixd projection = CameraMatrixManager.GetWorldProjectiond(distance, renderContext.graphicsDevice.Viewport.AspectRatio); Matrixd worldWVP = world * view * projection; Matrixd shipRot = Matrixd.CreateRotationZ(rotation + Math.PI) * Matrixd.CreateRotationX(Math.PI / 2 - camera.cameraRotY) * Matrixd.CreateRotationZ(camera.cameraRotX); return(shipRot * Matrixd.CreateScale(shipScale) * Matrixd.CreateTranslation(shipPos) * worldWVP); }
internal static Matrixd GetWorldProjectiond(double distance, double aspectRatio) { switch (MODE) { case 0: return(Matrixd.CreatePerspectiveFieldOfView(Math.PI / 2, aspectRatio, distance * 0.1f, distance * 100)); case 1: distance *= M_1; return(Matrixd.CreatePerspectiveFieldOfView(Math.PI / 4, aspectRatio, distance * 0.5f, distance * 2)); case 2: distance *= M_2; return(Matrixd.CreateOrthographicOffCenter(-0.2 * distance * aspectRatio, 0.2 * distance * aspectRatio, -0.2 * distance, 0.2 * distance, distance * 0.1, distance * 100)); case 3: return(Matrixd.CreatePerspectiveFieldOfView(Math.PI * 80 / 180, aspectRatio, distance * 0.1f, distance * 100)); } throw new NotImplementedException(); }
internal static Matrixd GetWorldViewd(double distance) { switch (MODE) { case 0: return(Matrixd.CreateLookAt(new Vector3d(0, -1 - distance, 0), new Vector3d(0, 0, 0), new Vector3d(0, 0, 1))); case 1: distance *= M_1; return(Matrixd.CreateLookAt(new Vector3d(0, -1 - distance * Math.Cos(angle), -distance * Math.Sin(angle)), new Vector3d(0, -1, 0), new Vector3d(0, 0, 1))); case 2: distance *= M_2; return(Matrixd.CreateLookAt(new Vector3d(0, -1 - distance * Math.Cos(angle), -distance * Math.Sin(angle)), new Vector3d(0, -1, 0), new Vector3d(0, 0, 1))); case 3: return(Matrixd.CreateLookAt(new Vector3d(0, -1 - distance * Math.Cos(angle), -distance * Math.Sin(angle)), new Vector3d(0, -1, 0), new Vector3d(0, 0, 1))); } throw new NotImplementedException(); }
private void Draw3D(GraphicsDevice graphicsDevice, SectorBounds bounds, ISector rootSector, RenderContext.LayerPass layerPass) { double relativeCameraZoom = camera.cameraZoom - Math.Log(ZCoords.GetSectorManager().GetTopmostOSMSectors().Count, 4) + (Game1.RECORDING ? 1 : 0); int zoomLevel = Math.Min(Math.Max((int)(relativeCameraZoom - 3), 0), ZCoords.GetSectorManager().GetHighestOSMZoom()); List <ISector> containedSectors = rootSector.GetSectorsInRange(bounds.minX, bounds.maxX, bounds.minY, bounds.maxY, zoomLevel); List <ISector> sorted = containedSectors.Where(x => x.GetRoot().Equals(rootSector)).ToList(); sorted.Sort((x, y) => x.Zoom.CompareTo(y.Zoom)); foreach (var sector in sorted) { IGraphicsBuffer buffer = loadedMaps[sector]; if (buffer is ImageTileBuffer) { continue; } SectorBounds b = new SectorBounds(bounds.minX * (1 << sector.Zoom) - sector.X, bounds.maxX * (1 << sector.Zoom) - sector.X, bounds.minY * (1 << sector.Zoom) - sector.Y, bounds.maxY * (1 << sector.Zoom) - sector.Y); SectorBounds limitedB = new SectorBounds(Math.Max(0, Math.Min(1, b.minX)), Math.Max(0, Math.Min(1, b.maxX)), Math.Max(0, Math.Min(1, b.minY)), Math.Max(0, Math.Min(1, b.maxY))); BasicEffect basicEffect = new BasicEffect(graphicsDevice); camera.ApplyMatrices(basicEffect); // going to make it easy and assume the shape is perfectly parallel (it's not) // the sector plane is constructed by flattening the visible portion of the sphere, basically Vector3d v1 = sector.ProjectToSphereCoordinates(new Vector2d(limitedB.minX, limitedB.minY)); Vector3d v2 = sector.ProjectToSphereCoordinates(new Vector2d(limitedB.maxX, limitedB.minY)); Vector3d v3 = sector.ProjectToSphereCoordinates(new Vector2d(limitedB.minX, limitedB.maxY)); Vector3d xAxis = (v2 - v1) / (limitedB.maxX - limitedB.minX); Vector3d yAxis = (v3 - v1) / (limitedB.maxY - limitedB.minY); Vector3d start = v1 - xAxis * limitedB.minX - yAxis * limitedB.minY; Vector3d zAxis = start * (xAxis.Length() + yAxis.Length()) / start.Length() / 2; // make this roughly the same length // matrixes copied over Matrixd world = Matrixd.CreateRotationZ(-camera.cameraRotX) * Matrixd.CreateRotationX(camera.cameraRotY); // eh.... think hard on this later double distance = 9 * Math.Pow(0.5, camera.cameraZoom); Matrixd view = CameraMatrixManager.GetWorldViewd(distance); Matrixd projection = CameraMatrixManager.GetWorldProjectiond(distance, graphicsDevice.Viewport.AspectRatio); Matrixd transformMatrix = new Matrixd(xAxis.X, xAxis.Y, xAxis.Z, 0, yAxis.X, yAxis.Y, yAxis.Z, 0, zAxis.X, zAxis.Y, zAxis.Z, 0, start.X, start.Y, start.Z, 1); // turns our local coordinates into 3d spherical coordinates, based on the sector Matrixd WVP = Normalize(transformMatrix * world * view * projection); // combine them all to allow for higher precision RenderContext context = new RenderContext(graphicsDevice, WVP, b.minX, b.maxX, b.minY, b.maxY, camera.cameraZoom, layerPass); buffer.Draw(context); } }
public Matrixd Kd; // kalman gain(nx x nz) // initialize the KalmanFilter class(double type) public KalmanFilterd(int nx, int nz, int nu, Matrixd initStateVector, Matrixd initEstimateUncertainty) { // define the dimensions of state vector, process noise vector and measurement noise vector nxd = nx; nzd = nz; nud = nu; // initialize the variables xd = new Matrixd(nxd, 1); zd = new Matrixd(nzd, 1); Fd = new Matrixd(nxd, nxd); ud = new Matrixd(nud, 1); Gd = new Matrixd(nxd, nud); Pd = new Matrixd(nxd, nxd); Qd = new Matrixd(nxd, nxd); Rd = new Matrixd(nzd, nzd); wd = new Matrixd(nxd, 1); vd = new Matrixd(nzd, 1); Hd = new Matrixd(nzd, nxd); Kd = new Matrixd(nxd, nzd); // assign the initial state vector and estimate uncertainty if (initStateVector.rows != xd.rows || initStateVector.columns != xd.columns) { throw new ArgumentException("Can not assign the initial state vector with different rows or columns.", nameof(initStateVector)); } else { xd = initStateVector; } if (initEstimateUncertainty.rows != Pd.rows || initEstimateUncertainty.columns != Pd.columns) { throw new ArgumentException("Can not assign the initial estimate uncertainty with different rows or columns.", nameof(initEstimateUncertainty)); } else { Pd = initEstimateUncertainty; } }
private Matrixd Normalize(Matrixd m) { var vals = new double[] { m.M11, m.M12, m.M13, m.M14, m.M21, m.M22, m.M23, m.M24, m.M31, m.M32, m.M33, m.M34, m.M41, m.M42, m.M43, m.M44 }; double scaleAmount = 1 / vals.Select(Math.Abs).Average(); m.M11 *= scaleAmount; m.M12 *= scaleAmount; m.M13 *= scaleAmount; m.M14 *= scaleAmount; m.M21 *= scaleAmount; m.M22 *= scaleAmount; m.M23 *= scaleAmount; m.M24 *= scaleAmount; m.M31 *= scaleAmount; m.M32 *= scaleAmount; m.M33 *= scaleAmount; m.M34 *= scaleAmount; m.M41 *= scaleAmount; m.M42 *= scaleAmount; m.M43 *= scaleAmount; m.M44 *= scaleAmount; return(m); }
protected override void Draw(GameTime gameTime) { RenderContext renderContext = new RenderContext(GraphicsDevice, Matrixd.Identity(), 0, 0, 0, 0, 0, RenderContext.LayerPass.TREE_DENSITY_PASS); foreach (var component in zComponents) { component.InitDraw(renderContext); } GraphicsDevice.SetRenderTargets(TREE_DENSITY_BUFFER); DrawAllComponents(renderContext, gameTime); renderContext.layerPass = RenderContext.LayerPass.GRASS_DENSITY_PASS; GraphicsDevice.SetRenderTargets(GRASS_DENSITY_BUFFER); DrawAllComponents(renderContext, gameTime); GraphicsDevice.BlendState = DEFERRED_RENDERING ? BlendState.Opaque : BlendState.AlphaBlend; renderContext.layerPass = RenderContext.LayerPass.MAIN_PASS; GraphicsDevice.SetRenderTargets(DEFERRED_RENDERING ? G_BUFFER : RENDER_BUFFER); DrawAllComponents(renderContext, gameTime); GraphicsDevice.BlendState = BlendState.AlphaBlend; if (DEFERRED_RENDERING) { GraphicsDevice.SetRenderTargets(RENDER_BUFFER); } DoComposite(); // draw UI directly to backbuffer? renderContext.layerPass = RenderContext.LayerPass.UI_PASS; DrawAllComponents(renderContext, gameTime); if (RECORDING) { OSMSectorLoader.SuperSave((Texture2D)RENDER_BUFFER[0].RenderTarget, Path.Combine(RECORD_PATH, $"frame{recordFrame}.png")); recordFrame++; } }
public CmdResult Execute(ExtendCmdData cmdData, ref string message) { var mainForm = cmdData.MainForm as Form; var viewForm = cmdData.ViewForm as IViewForm; if (viewForm == null) { return(CmdResult.Cancel); } var osgView = viewForm.View as ZfOsgViewCtrl; var osgObj = osgView.OsgObj; var skelroot = new Skeleton(); // 骨骼动画 skelroot.setDefaultUpdateCallback(); var root = new Bone(); // 骨骼 root.setInvBindMatrixInSkeletonSpace(Matrixd.inverse(Matrixd.translate(-1.0f, 0.0f, 0.0f))); root.setName("root"); var pRootUpdate = new UpdateBone("root"); // 骨骼更新器 pRootUpdate.getStackedTransforms().push_back(new StackedTranslateElement("translate", new Vec3f(-1.0f, 0.0f, 0.0f))); root.setUpdateCallback(pRootUpdate); var right0 = new Bone(); right0.setInvBindMatrixInSkeletonSpace(Matrixd.inverse(Matrixd.translate(0.0f, 0.0f, 0.0f))); right0.setName("right0"); var pRight0Update = new UpdateBone("right0"); pRight0Update.getStackedTransforms().push_back(new StackedTranslateElement("translate", new Vec3f(1.0f, 0.0f, 0.0f))); pRight0Update.getStackedTransforms().push_back(new StackedRotateAxisElement("rotate", new Vec3f(0.0f, 0.0f, 1.0f), 0.0)); right0.setUpdateCallback(pRight0Update); var right1 = new Bone(); right1.setInvBindMatrixInSkeletonSpace(Matrixd.inverse(Matrixd.translate(1.0f, 0.0f, 0.0f))); right1.setName("right1"); var pRight1Update = new UpdateBone("right1"); pRight1Update.getStackedTransforms().push_back(new StackedTranslateElement("translate", new Vec3f(1.0f, 0.0f, 0.0f))); pRight1Update.getStackedTransforms().push_back(new StackedRotateAxisElement("rotate", new Vec3f(0.0f, 0.0f, 1.0f), 0.0)); right1.setUpdateCallback(pRight1Update); root.addChild(right0); right0.addChild(right1); skelroot.addChild(root); Group scene = new Group(); BasicAnimationManager manager = new BasicAnimationManager(); scene.setUpdateCallback(manager); Animation anim = new Animation(); { var keys0 = new FloatKeyframeContainer(); // 关键帧容器 keys0.push_back(new FloatKeyframe(0.0, 0.0f)); keys0.push_back(new FloatKeyframe(3.0, (float)MathUtil.PI_2)); keys0.push_back(new FloatKeyframe(6.0, (float)MathUtil.PI_2)); var sampler = new FloatLinearSampler(); // 线性采样器 sampler.setKeyframeContainer(keys0); var channel = new FloatLinearChannel(sampler); // 通道 channel.setName("rotate"); channel.setTargetName("right0"); anim.addChannel(channel); } { var keys1 = new FloatKeyframeContainer(); // 关键帧容器 keys1.push_back(new FloatKeyframe(0.0, 0.0f)); keys1.push_back(new FloatKeyframe(3.0, 0.0f)); keys1.push_back(new FloatKeyframe(6.0, (float)MathUtil.PI_2)); var sampler = new FloatLinearSampler(); // 线性采样器 sampler.setKeyframeContainer(keys1); var channel = new FloatLinearChannel(sampler); // 通道 channel.setName("rotate"); channel.setTargetName("right1"); anim.addChannel(channel); } manager.registerAnimation(anim); manager.buildTargetReference(); // let's start ! manager.playAnimation(anim); // we will use local data from the skeleton MatrixTransform rootTransform = new MatrixTransform(); rootTransform.setMatrix(Matrixf.rotate((float)MathUtil.PI_2, new Vec3f(1.0f, 0.0f, 0.0f))); right0.addChild(createAxis()); right0.setDataVariance(Osg.Object.DataVariance.DYNAMIC); right1.addChild(createAxis()); right1.setDataVariance(Osg.Object.DataVariance.DYNAMIC); MatrixTransform trueroot = new MatrixTransform(); //trueroot.setMatrix(new Matrixf(root.getMatrixInBoneSpace().ptr())); trueroot.setMatrix(root.getMatrixInBoneSpace()); trueroot.addChild(createAxis()); trueroot.addChild(skelroot); trueroot.setDataVariance(Osg.Object.DataVariance.DYNAMIC); rootTransform.addChild(trueroot); scene.addChild(rootTransform); RigGeometry geom = createTesselatedBox(4, 4.0f); Geode geode = new Geode(); geode.Name = "2"; geode.addDrawable(geom); skelroot.addChild(geode); Vec3Array src = new Vec3Array(geom.getSourceGeometry().getVertexArray()); geom.setDataVariance(Osg.Object.DataVariance.DYNAMIC); initVertexMap(root, right0, right1, geom, src); scene.Name = "1"; osgObj.AddOrReplaceModel("Models", scene); osgObj.SetView(ViewMode.ShowAll); return(CmdResult.Succeed); }
// KalmanPredictd is called for predicting the state(second update for every iteration) public void KalmanPredictd() { // predict the discrete state and covariance xd = Matrixd.Mul(Fd, xd) + Matrixd.Mul(Gd, ud); Pd = Matrixd.Mul(Matrixd.Mul(Fd, Pd), Matrixd.Inverse(Fd)) + Qd; }
private void InitDraw(GraphicsDevice graphicsDevice, SectorBounds bounds, ISector rootSector) { double relativeCameraZoom = camera.cameraZoom - Math.Log(ZCoords.GetSectorManager().GetTopmostOSMSectors().Count, 4) + (Game1.RECORDING ? 1 : 0); // autoload stuff // TODO: move to update step? int zoomLevel = Math.Min(Math.Max((int)(relativeCameraZoom - 3), 0), ZCoords.GetSectorManager().GetHighestOSMZoom()); List <ISector> containedSectors = rootSector.GetSectorsInRange(bounds.minX, bounds.maxX, bounds.minY, bounds.maxY, zoomLevel); foreach (var pair in loadedMaps.Where(x => AllowUnload(x.Key, rootSector, containedSectors)).ToList()) { loadedMaps[pair.Key].Dispose(); loadedMaps.Remove(pair.Key); } // end autoload stuff if (toLoad != null || Constants.TO_LOAD != null) { if (Constants.TO_LOAD != null) { toLoad = ZCoords.GetSectorManager().FromString(Constants.TO_LOAD); } Stopwatch sw = new Stopwatch(); sw.Start(); foreach (var sector in toLoad.GetChildrenAtLevel(ZCoords.GetSectorManager().GetHighestOSMZoom())) { osmSectorLoader.GetGraphicsBuffer(graphicsDevice, sector).Dispose(); } Console.WriteLine($"Total load time for {toLoad} is {sw.Elapsed.TotalHours} h"); toLoad = null; if (Constants.TO_LOAD != null) { Constants.TERMINATE = true; Constants.TO_LOAD = null; } } bool loadCache = !(relativeCameraZoom - 4 > ZCoords.GetSectorManager().GetHighestOSMZoom()); foreach (var l in containedSectors) { if (loadCache) { if (!loadedMaps.ContainsKey(l)) { loadedMaps[l] = osmSectorLoader.GetCacheBuffer(graphicsDevice, l); } } else { if (!loadedMaps.ContainsKey(l) || loadedMaps[l] is ImageTileBuffer) { if (loadedMaps.ContainsKey(l)) { loadedMaps[l].Dispose(); } loadedMaps[l] = osmSectorLoader.GetGraphicsBuffer(graphicsDevice, l); } } } List <ISector> sorted = containedSectors.Where(x => x.GetRoot().Equals(rootSector)).ToList(); sorted.Sort((x, y) => x.Zoom.CompareTo(y.Zoom)); foreach (var sector in sorted) { IGraphicsBuffer buffer = loadedMaps[sector]; Matrixd projection = Matrixd.CreateOrthographicOffCenter(bounds.minX * (1 << sector.Zoom) - sector.X, bounds.maxX * (1 << sector.Zoom) - sector.X, bounds.maxY * (1 << sector.Zoom) - sector.Y, bounds.minY * (1 << sector.Zoom) - sector.Y, -1, 0.01f); // TODO: why negative? RenderContext context = new RenderContext(graphicsDevice, projection, bounds.minX * (1 << sector.Zoom) - sector.X, bounds.maxX * (1 << sector.Zoom) - sector.X, bounds.minY * (1 << sector.Zoom) - sector.Y, bounds.maxY * (1 << sector.Zoom) - sector.Y, camera.cameraZoom, RenderContext.LayerPass.MAIN_PASS); buffer.InitDraw(context); } }