How do I modify the GrabPointer prefab to allow for more than the default 64 colliders in a scene? - mrtk

I have a similar question to this, however for SpherePointer.
Using MRTK 2.2 as acquired by NuGet for Unity, I'm getting this warning pretty much every frame:
Maximum number of 64 colliders found in SpherePointer overlap query. Consider increasing the query buffer size in the pointer profile.
UnityEngine.Debug:LogWarning(Object)
Microsoft.MixedReality.Toolkit.Input.SpherePointerQueryInfo:TryUpdateQueryBufferForLayerMask(LayerMask, Vector3, QueryTriggerInteraction)
Microsoft.MixedReality.Toolkit.Input.SpherePointer:OnPreSceneQuery()
Microsoft.MixedReality.Toolkit.Input.FocusProvider:UpdatePointer(PointerData)
Microsoft.MixedReality.Toolkit.Input.FocusProvider:UpdatePointers()
Microsoft.MixedReality.Toolkit.Input.FocusProvider:Update()
Microsoft.MixedReality.Toolkit.<>c:<UpdateAllServices>b__63_0(IMixedRealityService)
Microsoft.MixedReality.Toolkit.MixedRealityToolkit:ExecuteOnAllServices(IEnumerable`1, Action`1)
Microsoft.MixedReality.Toolkit.MixedRealityToolkit:ExecuteOnAllServicesInOrder(Action`1)
Microsoft.MixedReality.Toolkit.MixedRealityToolkit:UpdateAllServices()
Microsoft.MixedReality.Toolkit.MixedRealityToolkit:Update()
I was able to successfully remove the similar warning for PokePointer using #Julia's response but I'm stumped as to how to do it for the GrabPointer prefab.
This prefab has a SpherePointer script attached but the SceneQueryBufferSize property isn't exposed in the inspector because SpherePointer's custom inspector (ShperePointerInspector.cs) doesn't expose it.

Great question! It looks like you've actually found a bug. Please use the following code to work around this for now, we will post a fix shortly. The issue to track this is here: issue 6878
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See LICENSE in the project root for license information.
using Microsoft.MixedReality.Toolkit.Input.Editor;
using Microsoft.MixedReality.Toolkit.Input;
using UnityEditor;
namespace Microsoft.MixedReality.Toolkit.Input
{
[CustomEditor(typeof(SpherePointer))]
public class SpherePointerInspector : BaseControllerPointerInspector
{
private SerializedProperty sphereCastRadius;
private SerializedProperty nearObjectMargin;
private SerializedProperty grabLayerMasks;
private SerializedProperty triggerInteraction;
private SerializedProperty sceneQueryBufferSize;
private bool spherePointerFoldout = true;
protected override void OnEnable()
{
base.OnEnable();
sphereCastRadius = serializedObject.FindProperty("sphereCastRadius");
sceneQueryBufferSize = serializedObject.FindProperty("sceneQueryBufferSize");
nearObjectMargin = serializedObject.FindProperty("nearObjectMargin");
grabLayerMasks = serializedObject.FindProperty("grabLayerMasks");
triggerInteraction = serializedObject.FindProperty("triggerInteraction");
}
public override void OnInspectorGUI()
{
base.OnInspectorGUI();
serializedObject.Update();
spherePointerFoldout = EditorGUILayout.Foldout(spherePointerFoldout, "Sphere Pointer Settings", true);
if (spherePointerFoldout)
{
using (new EditorGUI.IndentLevelScope())
{
EditorGUILayout.PropertyField(sphereCastRadius);
EditorGUILayout.PropertyField(sceneQueryBufferSize);
EditorGUILayout.PropertyField(nearObjectMargin);
EditorGUILayout.PropertyField(triggerInteraction);
EditorGUILayout.PropertyField(grabLayerMasks, true);
}
}
serializedObject.ApplyModifiedProperties();
}
}
}

Thanks Julia,
Since I can't modify SpherePointerInspector.cs in my project as the MRTK is obtained from NuGet and has no actual .cs files to edit. Here's the solution I came up with as a temporary workaround until MRTK 2.3 is released.
I replaced SpherePointer.cs with MySpherePointer.cs on a copy of the GrabPointer.prefab.
MySpherePointer.cs
using Microsoft.MixedReality.Toolkit.Input;
/// <summary>
/// This class exists soley to expose SpherePointer.queryBufferPointerSize which is
/// masked by the default SpherePointerInspector.
/// </summary>
public class MySpherePointer : SpherePointer
{
}
MySpherePointerInspector.cs
using Microsoft.MixedReality.Toolkit.Input;
using UnityEditor;
/// <summary>
/// This class exists soley to expose SpherePointer.queryBufferPointerSize which is
/// masked by the default SpherePointerInspector.
/// </summary>
[CustomEditor(typeof(MySpherePointer))]
public class MySpherePointerInspector : SpherePointerInspector
{
private SerializedProperty sceneQueryBufferSize;
private bool hiddenSpherePointerFoldout = true;
protected override void OnEnable()
{
base.OnEnable();
sceneQueryBufferSize = serializedObject.FindProperty("sceneQueryBufferSize");
}
public override void OnInspectorGUI()
{
base.OnInspectorGUI();
hiddenSpherePointerFoldout = EditorGUILayout.Foldout(hiddenSpherePointerFoldout, "Hidden Sphere Pointer Settings", true);
if (hiddenSpherePointerFoldout)
{
using (new EditorGUI.IndentLevelScope())
{
EditorGUILayout.PropertyField(sceneQueryBufferSize);
}
}
serializedObject.ApplyModifiedProperties();
}
}

Related

Azure Redis Cache and MVC Child Actions

I have successfully implemented Azure Redis Cache using the Microsoft RedisOutputCacheProvider from NuGet which works as expected for general pages.
[ChildActionOnly]
[ChildActionOutputCache(CacheProfile.StaticQueryStringComponent)]
public ActionResult Show(int id)
{
// some code
}
However, I can't seem to get it to work for child actions. Prior to using Redis Cache, it was working using the default OutputCacheProvider.
Does anyone have any ideas, or is it simply a limitation?
Thanks in advance
In your Global.asax.cs, set a custom child action output cache that talks to Redis:
protected void Application_Start()
{
// Register Custom Memory Cache for Child Action Method Caching
OutputCacheAttribute.ChildActionCache = new CustomMemoryCache("My Cache");
}
This cache should derive from MemoryCache and implement the following members:
/// <summary>
/// A Custom MemoryCache Class.
/// </summary>
public class CustomMemoryCache : MemoryCache
{
public CustomMemoryCache(string name)
: base(name)
{
}
public override bool Add(string key, object value, DateTimeOffset absoluteExpiration, string regionName = null)
{
// Do your custom caching here, in my example I'll use standard Http Caching
HttpContext.Current.Cache.Add(key, value, null, absoluteExpiration.DateTime,
System.Web.Caching.Cache.NoSlidingExpiration, System.Web.Caching.CacheItemPriority.Normal, null);
return true;
}
public override object Get(string key, string regionName = null)
{
// Do your custom caching here, in my example I'll use standard Http Caching
return HttpContext.Current.Cache.Get(key);
}
}
More info on my blog post

MvvmCross and UIButton.Selected UISegmentedControl Bindings, iOS

In a cross platform Xamarin app built with the MvvmCross framework I'm using a ToggleButton Widget in an Android .axml layout. I've bound the Checked property to a View Model property using a converter using the following binding syntax:
Checked MarketBuySellViewModel.Direction, Converter=DirectionBool, ConverterParameter='Sell'
Everything works well. On the iOS side, it appears you can use UIButton as a ToggleButton by using the Selected property. This implies that the following binding should achieve what I want on iOS:
set.Bind (SellButton).For(b => b.Selected).To (vm => vm.MarketBuySellViewModel.Direction).WithConversion("DirectionBool", "Sell");
I don't get any binding errors in the application output but the binding itself doesn't seem to work. Clicking the button doesn't set the Direction property and setting the direction to a different value does not set the Selected property on the UIButton.
Do I need to create a Custom Binding or am I simply setting up the binding incorrectly?
I also tried using a UISegmentedControl to achieve the same effect. Is binding to this control supported at all in MvvmCross? I don't see any reference to it in the source code. Does this mean I need to create custom bindings for it too?
For the UIButton, I don't believe there's any included Selected binding built into MvvmCross. Because of this - and because Selected doesn't have a simple paired event SelectedChanged, then I believe Selected binding should work one-way (from ViewModel to View) but not two-way.
There is a binding for the On of a UISwitch control and that's the control I've seen used most in these situations.
If you wanted to add a custom 2-way binding for Selected then I guess you'd have to do this using the ValueChanged event (but would need to check that is correct).
To do so, you'd just build a target binding something like:
public class MvxUIButtonSelectedTargetBinding : MvxPropertyInfoTargetBinding<UIButton>
{
public MvxUIButtonSelectedTargetBinding(object target, PropertyInfo targetPropertyInfo)
: base(target, targetPropertyInfo)
{
var view = View;
view.ValueChanged += HandleValueChanged;
}
private void HandleValueChanged(object sender, System.EventArgs e)
{
var view = View;
if (view == null)
return;
FireValueChanged(view.Selected);
}
public override MvxBindingMode DefaultMode
{
get { return MvxBindingMode.TwoWay; }
}
protected override void Dispose(bool isDisposing)
{
base.Dispose(isDisposing);
if (isDisposing)
{
var view = View;
if (view != null)
{
view.ValueChanged -= HandleValueChanged;
}
}
}
}
and this could be registered in Setup in protected override void FillTargetFactories(IMvxTargetBindingFactoryRegistry registry) using something like:
registry.RegisterPropertyInfoBindingFactory(typeof(MvxUIButtonSelectedTargetBinding), typeof(UIButton),
"Selected");
Similarly, I don't believe anyone has added a two way UISegmentedControl binding yet - but would happily see one added.
Building a two way UISegmentedControl binding would be quite straight-forward - you'd just have to bind to the pair SelectedSegment and ValueChanged - with code similar to above.
Alternatively, you could switch to using a custom MySegmentedControl which had a nicer Value`ValueChanged` pair which would automatically work without a custom binding - e.g.:
public class MySegmentedControl : UISegmentedControl
{
// add more constructors if required
public int Value
{
get { return base.SelectedSegment; }
set { base.SelectedSegment = value; }
}
}
If any or all of these custom bindings are needed, then the Mvx project is happy to get these bindings added as issues or pull requests along with test/demo UIs in the https://github.com/slodge/MvvmCross-Tutorials/blob/master/ApiExamples/ApiExamples.Touch/Views/FirstView.cs project
Could be helpful to someone else, so i'm sharing my experience. I needed a two way binding for UISegmentedControl.SelectedSegment property to a ViewModel. The one way biding (ViewModel => View) works by default. I couldn't able to properly utilize the solution proposed by Stuart - to subclass the UISegmentedControl. I tried to ensure that the linker does not rip off the new custom control code, but this didn't help me a bit. So a perfectly viable solution is the one with MvxPropertyInfoTargetBinding. Here is the code working ok for me:
public class MvxUISegmentedControlSelectedSegmentTargetBinding : MvxPropertyInfoTargetBinding<UISegmentedControl>
{
public MvxUISegmentedControlSelectedSegmentTargetBinding(object target, PropertyInfo targetPropertyInfo)
: base(target, targetPropertyInfo)
{
this.View.ValueChanged += HandleValueChanged;
}
private void HandleValueChanged(object sender, System.EventArgs e)
{
var view = this.View;
if (view == null)
{
return;
}
FireValueChanged(view.SelectedSegment);
}
public override MvxBindingMode DefaultMode
{
get { return MvxBindingMode.TwoWay; }
}
protected override void Dispose(bool isDisposing)
{
base.Dispose(isDisposing);
if (isDisposing)
{
var view = this.View;
if (view != null)
{
view.ValueChanged -= HandleValueChanged;
}
}
}
}
public class Setup : MvxTouchSetup
{
...
protected override void FillTargetFactories(IMvxTargetBindingFactoryRegistry registry)
{
registry.RegisterPropertyInfoBindingFactory(typeof(MvxUISegmentedControlSelectedSegmentTargetBinding), typeof(UISegmentedControl), "SelectedSegment");
}
}

EF4.1 hangs for 120 seconds when using Microsoft.ApplicationServer.Caching.DataCacheFactory

I have a consistent, repeatable 120 second hang whenever the application calls
this.cacheProvider.Add(new CacheItem(cacheKey, data, this.regionName), cachePolicy);
at line 60 of the CachedDataSource.cs of the sample.. The .Add method is internal to Microsoft's DLL and I don't have code to it. Here are my parameters:
cacheKey = "listofCompanies"
data = // this is an EF 4.0 database first model class with 70 entries... result from IQueryable
this.regionName = "companies"
Reproducing the error:
I have a database-first EF4.0 project that I recently upgraded to 4.1 by adding the "EntityFramework" reference and a ContextGenerator to my DAL.
If I undo these changes, then my application is instantly performant.
My DAL and repository are stored in a separate DLL from my MVC application. Not sure if this is playing a part of the issue.
About my repository
/// Sample repository. Note that I return List<T> as IEnumerable,
/// and I use IDisposable
///
public class CompanyRepository : DisposableBase, ICompanyRepository
{
public IEnumerable<CompanyDetail> GetOneCompany(int? CompanyID)
{
var t = from c in _entities.CompanyDetail
where c.CompanyID == CompanyID.Value
select c;
return t.ToList();
}
}
/// <summary>
/// Disposable implementation based on advice from this link:
/// from Http://www.asp.net/entity-framework/tutorials/implementing-the-repository-and-unit-of-work-patterns-in-an-asp-net-mvc-application
/// </summary>
public class DisposableBase : IDisposable
{
protected TLSAdminEntities1 _entities;
public DisposableBase()
{
_entities = new TLSAdminEntities1();
disposed = false;
}
private bool disposed ;
protected virtual void Dispose(bool disposing)
{
if (!this.disposed)
{
if (disposing)
{
_entities.Dispose();
}
}
this.disposed = true;
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
}
Question
Is this a bug, or am I using EF4.1, or the Caching layer incorrectly?
You mention that data is the result of IQueryable. Have you tried to perform .ToList() first on the data before sending it over to cache?

XNA 4.0 Graphics Device Error

I know that the way the declaration of the graphics device is suppose to look in the main Game1() constructor is:
GraphicsDeviceManager graphics;
graphics = new GraphicsDeviceManager(this);
then you can use stuff like:
graphics.PreferredBackBufferWidth = 1366;
But if I declare the same inside a separate class, what do I fill in for "this"?
GraphicsDeviceManager graphics;
graphics = new GraphicsDeviceManager(?);
EDIT:
After modifying everything as you said, I now get a error that sends me to this line of code:
/// <summary>
/// Event handler for when the Play Game menu entry is selected.
/// </summary>
void PlayGameMenuEntrySelected(object sender, PlayerIndexEventArgs e, Game game)
{
LoadingScreen.Load(ScreenManager, true, e.PlayerIndex,
new GameplayScreen(game));
}
This program is the menu sample you can get from Microsoft, heavily modified of course, this is the code that executes when you hit enter on the main menu screen with "Play Game" highlighted. I guess the problem is passing the variable.
Edit 2:
I fixed the code I think but now it sent me to this line and I don't know how to edit it.
playGameMenuEntry.Selected += PlayGameMenuEntrySelected;
You need a reference to your Game instance. I'd just pass it to your new class constructor.
For example, if you want to move the GraphicsDeviceManager instance into a separate class, Foo,
/// <summary>
/// This is the main type for your game
/// </summary>
public class Game1 : Microsoft.Xna.Framework.Game
{
private Foo _foo;
public Game1()
{
_foo = new Foo(this);
}
protected override void Dispose(bool disposing)
{
if (_foo != null)
{
_foo.Dispose();
_foo = null;
}
base.Dispose(disposing);
}
}
public class Foo : IDisposable
{
private Game _game;
private GraphicsDeviceManager _graphics;
private SpriteBatch _spriteBatch;
public Foo(Game game)
{
_game = game;
_game.Content.RootDirectory = "Content";
_graphics = new GraphicsDeviceManager(_game);
_spriteBatch = new SpriteBatch(_game.GraphicsDevice);
}
public void Dispose()
{
if (!_spriteBatch.IsDisposed)
{
_spriteBatch.Dispose();
_spriteBatch = null;
}
}
}
Update
It's important to properly dispose of a lot of XNA objects (otherwise, you get memory leaks). See Foo.Dispose() and the Game1.Dispose() override above.

How do I create a program that details files and their sub directories?

There is a program that I am working on and Im absolutly lost even at how to begin this. I am using Visual Studio C# Windows App Form.
What I need to do is allow the user to enter any path location they want and the program will return the Name of the file/folder; Path; date and size, and this will also be done for sub directories.
I found some code in the MSDN site and I am trying to use it and modify it for the first part of this project, but keep receiving error messages. Some of the messages indicate that there is more than one entry ie (static void Main() and using namespace Detailed).
This is what I have so far, a form with rich text box and the FolderBrowserDialog and it seems as I can't get beyond this point without so many errors.
This is under Form1.Designer.cs:
<i>namespace Detailed
{
partial class Form1
{
///
/// Required designer variable.
///
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.folderBrowserDialog1 = new System.Windows.Forms.FolderBrowserDialog();
this.richTextBox1 = new System.Windows.Forms.RichTextBox();
this.openFileDialog1 = new System.Windows.Forms.OpenFileDialog();
this.SuspendLayout();
//
// folderBrowserDialog1
//
this.folderBrowserDialog1.HelpRequest += new System.EventHandler(this.folderBrowserDialog1_HelpRequest);
//
// richTextBox1
//
this.richTextBox1.Location = new System.Drawing.Point(12, 32);
this.richTextBox1.Name = "richTextBox1";
this.richTextBox1.Size = new System.Drawing.Size(167, 23);
this.richTextBox1.TabIndex = 0;
this.richTextBox1.Text = "";
//
// openFileDialog1
//
this.openFileDialog1.FileName = "openFileDialog1";
//
// Form1
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(284, 262);
this.Controls.Add(this.richTextBox1);
this.Name = "Form1";
this.Text = "Form1";
this.Load += new System.EventHandler(this.Form1_Load);
this.ResumeLayout(false);
}
#endregion
private System.Windows.Forms.FolderBrowserDialog folderBrowserDialog1;
private System.Windows.Forms.RichTextBox richTextBox1;
private System.Windows.Forms.OpenFileDialog openFileDialog1;
}
}
For the For1.cs this is what I have so far:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
public class FolderBrowserDialogExampleForm : System.Windows.Forms.Form
{
private FolderBrowserDialog folderBrowserDialog1;
private OpenFileDialog openFileDialog1;
private RichTextBox richTextBox1;
private MainMenu mainMenu1;
private MenuItem fileMenuItem, openMenuItem;
private MenuItem folderMenuItem, closeMenuItem;
private string openFileName, folderName;
private bool fileOpened = false;
public partial class Form1 : Form
{
public Form1()
{
}
private void Form1_Load(object sender, EventArgs e)
{
}
private void folderBrowserDialog1_HelpRequest(object sender, EventArgs e)
{
}
}
private void InitializeComponent()
{
this.SuspendLayout();
//
// FolderBrowserDialogExampleForm
//
this.ClientSize = new System.Drawing.Size(284, 262);
this.Name = "FolderBrowserDialogExampleForm";
this.ResumeLayout(false);
}
}
I'm still new to programing and hope I can get this figured out asap as I was requested to have this no later than Thursday morning est. I had the Rich TextBox in the Form, but removed it because of too many errors.
This is the code I found. I know this is just part of what I need to do, but when reading through the code I noticed that maybe I can apply what is needed to the form and then break up the code and put the pieces of code where I need them. This is the code I am following
Here is an error message I am receiving with Form1.Designer.cs - there are 14 of these same errors:
‘Detailed.form1’ does not contain a definition for ‘Form1_Load’ and no extension method ‘Form1_Load’ accepting a first argument of type ‘Detailed.Form1’ could be found (are you missing a using directive or an assembly reference?)
The first thing you want is a dialog prompting the user for a directory.
So get rid of all that code, start a new project win form and place a textbox in your form and a button in your form.
Simple enough one text box and one button. Now in the click event of your button "Browse", have you, you write code to open an instance of the FolderBrowserDialog class and you .ShowDialog().
To get this path:
Here is a sample screen output:
The code is fairly straightforward, look at my picture and how much code i have to do this.

Resources