DayDream, detect pointer without using Event System - google-vr

Google's new DayDream samples are using the Event System to detect if the pointer is on an object.
Previously it wasn't working like that at all, it was a reticle, and you would then create a Raycast between the Camera and the reticle, such as:
Vector3 rayDirection = GvrController.Orientation * Vector3.forward;
if (Physics.Raycast(origin, rayDirection, out hitInfo, Mathf.Infinity)) {
And then you detect if a specific Object is between the reticle and the Camera.
This way doesn't exactly work anymore. Google is now using the event system, and then checking if the reticle is positioned on an object.
Is there a way for me to check that for any object without using the Event System.
The Event System is a good method, it's just I have about 40 different objects that all work the same way, and implementing an event point/click for these 40 different objects seems like an overkill when previously I could just check an object by tag.
Anyone was able by any chance to be able to detect if the pointer is positioned on an object without using the Event system?
Raycasts don't seem to properly work anymore as the pointer seems to be more of a 2D object, just like a Mouse.
This works approximately, but not very well:
Vector3 origin = Head.transform.position + GvrController.ArmModel.wristPosition;
Vector3 rayDirection = GvrController.ArmModel.pointerRotation * Vector3.forward;
Any help would be appreciated :)

If you don't want to use EventTrigger component, you can simply use your same old script and implement IPointerEnterHandler, IPointerExitHandler, OnPointerClickHandler etc and use same compare tag method for every object.
I think its much more easy to use than custom raycast. As there is always a Graphics Raycaster (or Physics Raycaster for 3D Objects) at work so why not use what it has to offer.
public class MyOldScriptWhichUsedRaycasting: MonoBehaviour, IPointerEnterHandler, IPointerExitHandler, IPointerClickHandler
{
public void OnPointerEnter (PointerEventData eventData)
{
if(gameObject.CompareTag("Grabable"))
{
//do stuff here.
}
}
public void OnPointerExit (PointerEventData eventData)
{
if(gameObject.CompareTag("Grabable"))
{
//do stuff here.
}
}
public void OnPointerClick (PointerEventData eventData)
{
if(gameObject.CompareTag("Grabable"))
{
//do stuff here.
}
}
}
Hope this helps

Related

JavaFX - How to use ImageView methods on Object type?

I'm trying to create an EventHandler for the mouse dragged event. I'll use this same handler to do the same thing with several ImageViews. Now this is what I did.
static EventHandler<MouseEvent> dragHandler = new EventHandler<MouseEvent>() {
#Override
public void handle(MouseEvent e) {
e.getSource().toFront();
e.getSource().setTranslateX(e.getSceneX() );
e.getSource().setTranslateY(e.getSceneY() );
}
};
But apparently I can't use toFront or setTranslate methods or anything that I used for ImageViews because e.getSource returns an Object and these are ImageView methods that are not available to Object type. And apparently I can't simply cast that into an ImageView either by doing
(ImageView)( e.getSource() ).toFront();
I could simply use inner classes and lambda expressions but I thought there must be a more efficient way than just copy pasting the same lines like 15 times for each ImageView. So please enlighten me if there is.
Thanks in advance.
Casting would work, but the precedence of casting is below that of dereferencing (.), so your code example tries to downcast the result of (e.getSource()).toFront(), which doesn't work (as that has no type, since toFront() is void).
So
((ImageView) e.getSource() ).toFront();
would work.
However, it's usually better to register a different handler for each image view. There's no need to repeat code: just use any standard programming technique to avoid doing so. E.g. you can write a method:
private void registerEventHandler(ImageView imageView) {
imageView.setOnMouseDragged(e -> {
imageView.toFront();
imageView.setTranslateX(e.getSceneX() );
imageView.setTranslateY(e.getSceneY() );
});
// register other event handlers, as needed.
}
and then call the method for each image view (in a loop, if you have them in some suitable data structure).
Alternatively, you could create a method that creates the image views and registers any necessary handlers.
As well as being arguably cleaner code, these techniques also avoid the downcast, which in general is a good thing.

How to turn off Motion Controller line pointer

That's it, I'll step on my pride!
I'm using MRTK v2 and working fine except that at some point I want to turn off the line extending from the Motion Controller to the object and that provides input. After looking around and trying to find it in the MRTK documentation (it's gotta be easy, right?), I'm still banging my head on the wall and it's starting to hurt....
The MRTK documentation explains quite well how to configure it here:
https://github.com/microsoft/MixedRealityToolkit-Unity/blob/mrtk_release/Documentation/Input/Pointers.md
But I'm looking to do this in script, enabling and disabling it as I need it in my application.
Any clue how to do this?
Many thanks!
Answered my own question. Simple:
PointerUtils.SetMotionControllerRayPointerBehavior(PointerBehavior.AlwaysOff);
See documentation here: https://github.com/microsoft/MixedRealityToolkit-Unity/blob/mrtk_release/Documentation/Input/Pointers.md
Great question! Here's one way to do this that has worked for me. You can see my solution at this repository: https://github.com/julenka/MixedRealityToolkit-Unity/tree/so/linepointer_off. Open the scene Assets/TurnOffLinePointerTest.unity and then use hand simulation to press the buttons. The code to turn the pointers on/off is in Assets/PointerConfigurationExample.cs.
Note: the reason you need to use this approach of modifying the mediator instead of directly setting myPointer.IsActive = false is because the default mediator overwrites these values every frame. Luckily, you can customize this behavior.
Step 1: Update MRTK a bit so that PointerMediator can be accessed
Apply the changes from this commit to your MRTK clone. This change updates the FocusProvider in MRTK to make the PointerMediator publicly accessible, and makes the DefaultPointerMediator extensible by updating fields to be protected instead of private, and making methods virtual. See this pull request that implements this change directly into MRTK.
Step 2: Create a custom PointerMediator that will turn off far pointers
Create a custom Pointer Mediator like the one from this commit.
using System.Collections.Generic;
using Microsoft.MixedReality.Toolkit.Input;
public class CustomPointerMediator : DefaultPointerMediator
{
public bool FarPointersDisabled {get; set;}
public override void UpdatePointers()
{
base.UpdatePointers();
if (FarPointersDisabled)
{
foreach(var pointer in farInteractPointers)
{
pointer.IsActive = false;
}
}
}
}
Note that this mediator extends DefaultPointerMediator so it adapts almost all the default mediator logic. Make sure you have fully applied the changes from the first commit otherwise you will not be able to extend DefaultPointerMediator.
Step 3: Tell MRTK to use your custom pointer mediator
In your pointer profile, configure MRTK to use the custom pointer mediator instead of the default pointer mediator. Notice in the picture that I've created a custom pointer profile as part of a custom input system (don't modify the default profile otherwise your changes might get overwritten when you update MRTK).
Step 4: Component that uses custom mediator to turn line pointers on / off
You can now write your component which will use your custom mediator to turn the line pointers on and off.
public class PointerConfigurationExample : MonoBehaviour
{
/* Turns off all far interaction pointers */
public void TurnOffFarPointers()
{
Debug.Log("Line pointers off");
SetFarPointersDisabled(true);
}
public void TurnOnFarPointers()
{
Debug.Log("Line pointers on");
SetFarPointersDisabled(false);
}
private void SetFarPointersDisabled(bool isDisabled)
{
FocusProvider focusProvider = (FocusProvider) MixedRealityToolkit.InputSystem.FocusProvider;
if (focusProvider != null)
{
foreach(var mediator in focusProvider.PointerMediators)
{
// Note: you could check here to make sure you only disable pointers for hands
CustomPointerMediator myMediator = (CustomPointerMediator) (mediator.Value);
if (myMediator != null)
{
myMediator.FarPointersDisabled = isDisabled;
}
}
}
}
}

Integrating smart pointers with legacy code raw pointers

I have a situation, where I have existing code that works with raw pointers, and I'm not permitted to smart-pointer-ify it. However, I am permitted to use smart pointers in any new code I develop.
For example.
I have an existing function like:
void processContent()
{
ContentObject * myContent = new ContentObject();
newFunction(myContent);
}
void newFunction(ContentObject * content)
{
// myVector is just a std::vector<ContentObject*>, defined elsewhere
myVector.push_back(content);
}
void doSomethingWithContent()
{
// There is some logic here, but ultimately based on this logic I want to remove entries, and free the memory they point to.
myVector.pop_back();
}
I have control over the content of "newFunction" and "doSomethingWithContent". But the argument passed into newFunction is fixed. Obviously I could manually delete the pointer in myVetor, before popping it, but I wondered if I can implement smart pointers here so that it happens "automatically" for me?
Can I take a raw pointer passed into a function, and turn it into a unique_ptr, then add this to a container, and have it delete the memory when it's popped from the container?
Thanks
Joey
Assume that you can define your myVector as the following:
std::vector<std::shared_ptr<ContentObject>> myVector;
In that case you can switch on smart pointers in your code and myVector will keep all your objects as you expected:
void newFunction(ContentObject * content)
{
myVector.push_back(std::shared_ptr<ContentObject>(content));
}
void doSomethingWithContent()
{
// There is some logic here, but ultimately based on this logic I want to remove entries, and free the memory they point to.
myVector.pop_back();
}

Flex: Which way should I add this event handler?

I use a unit of work pattern a lot in my flex projects. I'll have a class that might call a web service, put the data in a sqlite db, refresh a model with the data then raise an event.
I usually call these inline and pass in some singleton classes:
protected function CareerSynced():void
{
var process:ProcessWorkouts = new ProcessWorkouts(_dataModel, _trainerModel, _databaseCache, _database.Conn);
process.addEventListener("AllWorkoutsProcessed", AllWorkoutsProcessed);
process.UpdateAllUnprocessed();
}
I'll then get the response like this:
private function AllWorkoutsProcessed(event:DataReceivedEvent):void
{
//do something here
}
My question is, am I adding that event listener correctly? I think I might be causing a memory leak, but I'm not sure. I've also thought about using a weak reference. I'm confused about when to use them. Would this be one of those cases?
Should it be like this?
process.addEventListener("AllWorkoutsProcessed", AllWorkoutsProcessed,false, 0, true);
I would either go with the weak reference or just remove the listener:
private function AllWorkoutsProcessed(event:DataReceivedEvent):void
{
event.target.removeEventListener("AllWorksoutsProcessed",AllWorkoutsProcessed);
}
I could list out my reasons but I'll just point you to this.

Flex-IFrame Comm Test Not Working

I'm trying to get the IFrameCommTest example (from the Flex-IFrame site) to work in Flex 4, and, while the IFrame itself works, the communication does not. In particular, I need to get the included HTML page to call functions from the flex app (I already have a way to get the Flex app to talk to the HTML).
I've exported the project to facilitate your help.
The problem, I suspect, is that the "parent.FABridge" doesn't exist. My guess is that something in flex4 changed with regard to how things are located in the DOM.
(This post is related to the earlier post about FABridge.
I thought this would be a clearer example of the problem. )
Thanks,
Brian
I've solved this my own self :D
The difference over the mechanism above is in the getFlexApp() function, and it provides a way to, well, get the flex object. Once the objecty it gotten, I just call the EIButtonClicked() function, and pass a value to it.
function getFlexApp(appName) {
if (navigator.appName.indexOf ("Microsoft") !=-1) {
return window.top[appName];
} else {
return window.top.document[appName];
}
}
function callFlexFunction() {
var sTxt ;
sTxt = document.getElementById('txt1').value;
alert('HTML/Javascript wants to tell you about ' + sTxt);
getFlexApp('iframeCommTest').EIButtonClicked(sTxt) ;
}
Meanwhile, the flex side has an external interface callback established. You can see that the "EIButtonClicked" referenced in the JS above is matched by the label for the callback in the AS below.
/**
* When the button is clicked.
*/
public function onEIButtonClicked(data:String):void {
Alert.show("Flash wants to tell you about " + data);
}
protected function application1_creationCompleteHandler():void {
// TODO Auto-generated method stub
if (ExternalInterface.available) {
ExternalInterface.addCallback("EIButtonClicked", onEIButtonClicked);
}
}

Resources