How to change camera position/walk in aframe vr with accelerometer? - aframe

(I know it will be unstable but I still want to try it)
I want to move around in aframe scene using accelerometer
AFRAME.registerComponent('acccam',{
window.addEventListener('devicemotion', function(){
var acc = event.acceleration;
this.el.object3D.position.x += acc.x*9.8;
this.el.object3D.position.y += acc.y*9.8;
this.el.object3D.position.z += acc.z*9.8;
}, true);
})
I expect the camera to move or at least shake/something but nothing is happening could getelement by id, get attribute and set attribute be used to update the position by taking temporary values and then cloning them if yes then how?

Make sure the event is firing, and make sure you don't have like look-controls also enabled on the same entity or it will be overridden.
You can need to make sure this is the correct pointer. When you wrap in function (), this becomes window. You can use (evt) => { instead of function (evt) {

Related

QML Event before and after property change

Are there any signals I can bind to that allow me to execute functions directly before and directly after a property changes?
For example something like this:
Canvas {
id: canvas
anchors.fill: parent
property real lastX
property real lastY
property var lastContext
function cacheImage(){
lastContext = canvas.context
}
function loadImageFromCache(){
canvas.context = lastContext
canvas.requestPaint()
}
}
I want to call the cacheImage() function right before the canvas's size changes and the loadImageFromCache() right after the resize is completed.
If I understand correctly the onWidthChanged and onHeightChanged do the latter, but I need to save the image before it does that. Is there a simple way to do this?
But cacheImage() doesn't have to be called right before the size changes! It needs to be called any time after the most recent canvas contents change, and before the new canvas size takes effect. The window to cache the canvas is very long and extends between changes. The event "before n-th property change" is simply "after (n-1)-th property change" :)
This kind of functionality is not part of the "core design intent" of QML, so you are not getting it out of the box.
It is quite easy to do for C++ objects when you get to implement your own setter function.
But even in QML you can simply use an auxiliary setter function rather than using the property directly:
function setSomeProp(newValue) {
if (newValue === oldValue) return
stuffBeforeChange()
oldValue = newValue
stuffAfterChange() // optional, you can use the default provided signal too
}
If you insist on using a property based syntax, you can use an additional auxiliary property:
property type auxProp
onAuxPropChanged: setSomeProp(auxProp)
Which will allow you to use the = operator as well as do bindings.

openui5 1.38 attach event scrollbar

from the last version update (from openui5 1.36.12 to openui5 1.38.4) the following code is not working anymore:
var myTable = new sap.ui.table.Table();
myTable ._oVSb.attachScroll(function() {
colorTheTableRows();
})
I'm using the "attachScroll" event in order to color the table rows with a specific logic.
Since last openui5 version update I get this error in console:
Uncaught TypeError: Cannot read property 'attachScroll' of undefined
I've tried to debug the problem and it seems that the object _oVSb has be removed from sap.ui.table.Table.
My final goal is to paint the rows with different colors based on the content ... is there any other way to reach this feature?
Thanks
Even i want this event some how came to this thread. i tried #Dopedev solution it was not working then i changed bit in that as below
$("#<tablid>-vsb").scroll(function() {
console.log("Table is scrolled")
});
instead of getting the tbody get the table-id-vsb and attach the scroll function
You can still get scroll event for your table using .scroll() of jQuery.
onAfterRendering: function(){
//Register handler for scroll event
$("tbody").scroll(function(){
// your stuff
});
}
Demo
I know that one of the earlier posts was already marked as the 'right' answer, but it did not work for me, so I thought I would post my working solution, as it might be helpful to others. The following code will work to effectively 'attach' to the vertical scroll event of a table in 1.38:
onAfterRendering: function() {
if (this.firstTime) { //You only want to override this once
var oTable = this.getView().byId("<YOUR_ID_HERE>");
//Get a reference to whatever your custom handler is
var oHandler = this.handleScroll;
//Store a reference to the default handler method
var oVScroll = oTable.onvscroll;
oTable.origVScrollHandler = oVScroll;
oTable.onvscroll = function(i) {
//Call the 'default' UI5 handler
oTable.origVScrollHandler(i);
//Call your handler function, or whatever else you want to do
oHandler();
};
this.firstTime = false;
}
},
var myTable = new sap.ui.table.Table("myTable");
After rendering:
sap.ui.getCore().byId("myTable-vsb").attachScroll(function() {
colorTheTableRows();
})

Select a game object and perform actions using GUI.Button (EventTrigger)

I am currently working on a strategy game and I want to preform actions using GUI.Button on game objects. I am using ray cast and mouse click to select the object however when I click on GUI.Button to take out another action the button disappears. I want to use that button to open up another GUI.Box to show some descriptions.
I know why the button is disappearing, it is because I am projecting the ray cast to my button clicks in the update function but how can I avoid this? I also know that I have to use EventTrigger however I am not familiar with javascript event trigger, I searched online but I couldn't find any helpful javascript.
Screenshots:
Here is my script:
#HideInInspector
var isCalled:int = 0;
#HideInInspector
var scWidth:int = 0;
#HideInInspector
var scHeight:int = 0;
function Start () {
scWidth = Screen.width;
scHeight = Screen.height;
}
function Update () {
if (Input.GetMouseButtonDown(0)) {
var ray : Ray = Camera.main.ScreenPointToRay (Input.mousePosition);
var hit : RaycastHit;
if (Physics.Raycast (ray, hit)) {
if (hit.collider.tag == "House") {
isCalled = 1;
} else{
isCalled = 0;
}
}
}
}
function OnGUI(){
if(isCalled==1)
GUI.Button(Rect(scWidth/2,(scHeight/2)+(scHeight/4),120,120), name);
}
}
If I understood you right, the problem is that when you click on button the raycast is fired up before button click and you select different object or no object at all and button disappears or reappears but for another object, what you need to do is check if you clicked on GUI and if yes don't project the raycast that selects the objects. Here is how you are gonna do it.
var selectedUI : GameObject = EventSystem.current.currentSelectedGameObject;
if (Input.GetMouseButtonDown(0) && selectedUI) {
var ray : Ray = Camera.main.ScreenPointToRay (Input.mousePosition);
var hit : RaycastHit;
if (Physics.Raycast (ray, hit)) {
if (hit.collider.tag == "House") {
isCalled = 1;
} else{
isCalled = 0;
}
}
}
I work in C#, so I might have done some syntax errors, but the logic is right.
There is a good trick when using legacy GUI system to avoid raycast when mouse is over GUI elements. Using tooltip to controll if you may cast your ray =)
Something like this (I also don't work with US so may I it needs some work):
var hover : String;
function OnGUI(){
if(GUI.Button (Rect (10,10,100,20), "My Button"));
hover = GUI.tooltip;
function Update () {
if(hover != "") {
// raycast logic
}
}
If you need to avoid raycast when your "popUp" window/panel is shown but you don't want a tooltip on it you may approach using a MouseOverGUI manager too.
It is just a static or singleton holding a boolean that you will set true when your mouse is over some rect that you don't want to cast rays using Rect.Contains(Event.current.mousePosition) and to false whenever it runs out of this rect.
Use this bool with or without tooltip var to allow raycast:
if(!MouseManager.MouseOverGUI) {
// raycast logic
}
Note that creating your rect on each OnGUI cycle will difficult to catch it and control the MouseOveGUI. Also it is a bad practice for performance because OnGUI runs more than once per frame so I'll suggest you to create you rects just once (recalculate it just when needed) and pass it to your GUI elements ;)
I think the easiest way is to create a GameObject(input blocker) which is not visible but have a collider. Place it in between the camera and level objects and deactivate it. When you select a GameObject using Raycast you enable that input blocker GameObject and place it around the area of selected GameObject and GUI. Then you have to ignore the selection if raycast is collided with Input Blocker. When you deselect the Gameobject then you deactivate input blocker
You should also maintain current state of the game for example:
enum State
{
NothingSelected = 0,
GameobjectSelected,
BigMenuOpen
}
State currentState;
So according to state you can define the behavior on mouse click. Like if Full screen menu is Open then raycast does not fire.

Redrawing the globe

When toggling the visibility of 3D KmlPolygons or modifying style properties the globe doesn't update directly afterwards. Rather, you need to trigger an update by moving your mouse around. There's an internal redraw function that's only called at certain times, but I don't know how to invoke it.
To get the map to update I've made this function:
redraw : function (ge) {
ge = setDefault(ge, this.ge);
if (typeof obj == 'undefined' && ge) {
Log.info('Earth redraw');
ge.getWindow().setVisibility(false);
ge.getWindow().setVisibility(true);
} else {
Log.error('Earth redraw failed');
}
}
It toggles the window visibility and forces an update, but this causes a flash on some computers and isn't too elegant. Is there an alternative?
Try to copy the camera and set it again. I don't know if this will work, but if it works it should not make any flash
var lookAt = ge.getView().copyAsLookAt(ge.ALTITUDE_RELATIVE_TO_GROUND);
ge.getView().setAbstractView(lookAt);

Capturing mouseEevents on a container, bypassing its children

I am building an RIA application using Flex 4.6 that contains a main borderContainer (page) that can contain some other borderContainers (graphic or text elements).
I added an event listener on the page to listen to click events:
page.addEventListener(MouseEvent.CLICK, clickHandler, true);
clickHandler looks like this:
private function clickHandler(event:MouseEvent):void
{
// Remove event listeners
page.removeEventListener(MouseEvent.CLICK, clickHandler, true);
// Get click position
objX = event.localX;
objY = event.localY;
}
My problem is that although the event's currentTarget is always the page (normal), the target can either be the page or one of its children, and then localX doesn't give me the position on the page but on the child.
Is there a way to make sure the page is always the target of the event? Something like stopping the capturing phase on the page so it doesn't go deeper?
Thanks in advance for your help
Darrel
I think you may be asking the wrong question. As I understand it, you want the x/y position relative to 'page'. You can use the DisplayObject#globalToLocal() function to find this.
Just take the the global coordinates and convert them to local coordinates relative to 'page':
var coordinates:Point = new Point(event.stageX, event.stageY);
coordinates = page.globalToLocal(coordinates);
objX = coordinates.x;
objY = coordinates.y;

Resources