HERE SDK Orientation change too late - heremaps

I am using HERE-Android-SDK to build a simple navigation solution with offline maps.
In order to automatically center and rotate the map (depending on location and orientation of the user) I am using the PositioningManager class from the HERE-SDK. It seems that the orientation update is some seconds too late when an active navigation is running.
I am using the following code snippets to do so.
val positioningManager = PositioningManager.getInstance()
positioningManager.addListener(WeakReference(positionListener))
positioningManager.start(PositioningManager.LocationMethod.GPS)
var positionListener = object : PositioningManager.OnPositionChangedListener {
override fun onPositionFixChanged(
p0: PositioningManager.LocationMethod?,
p1: PositioningManager.LocationStatus?
) {
// do nothing here
}
override fun onPositionUpdated(
method: PositioningManager.LocationMethod?,
position: GeoPosition?,
isMapMatched: Boolean
) {
if (position == null) return
// update map center and orientation
}
}
override fun onPause() {
positioningManager.stop()
}
override fun onResume() {
positioningManager.start(PositioningManager.LocationMethod.GPS)
}
Is there anything I can do to avoid the too late orientation update?
Thanks for all of your help in advance!

Related

SwiftUI Drag&Drop: Accessing the dragged item in validateDrop

G'day everyone,
I'm trying to interrogate the dragged object during the validate phase of drag and drop in SwiftUI, but haven't been able to make it work. Here's my validateDrop method:
func validateDrop(info: DropInfo) -> Bool {
print("Drop Validating")
print ("Dropping into slot where \(rosterPlayer!.givenName!) \(rosterPlayer!.surname!) is")
guard info.hasItemsConforming(to: [PlayerShirtUTT.uti.identifier]) else {
return false
}
let itemProviders = info.itemProviders(for: [PlayerShirtUTT.uti.identifier])
guard let itemProvider = itemProviders.first
else {
return false
}
print ("Lets check")
itemProvider.loadObject(ofClass: Player.self) { player, _ in
let player = player as? Player
// Do the player checks here
print ("Player check code")
}
return true
}
Exactly the same code in my performDrop method works fine... can anyone point me in the right direction here please?
If anyone else is looking for an answer to this, the answer is you can't.
Documentation reference:
https://developer.apple.com/documentation/uikit/drag_and_drop/making_a_view_into_a_drop_destination
The content of the dragged item is only available asynchronously after the drop is concluded (i.e. only in perdormDrop() ).
So, now I'm looking at ways to use the UTT as a distinguishing identifier for the same base data.

Unreal Engine 4: C++ Delegate not being called

I've been working on converting some blueprint logic over to C++. One of the things I have is a button. The button can be pressed in VR and has a delegate that is called to notify any registered functions that the button press occurred. Here is how the delegate is declared in the AButtonItem.h class.
#pragma once
#include "BaseItem.h"
#include "ButtonItem.generated.h"
DECLARE_DYNAMIC_MULTICAST_DELEGATE(FButtonItemPressedSignatrue);
UCLASS()
class AButtonItem : public ABaseItem
{
GENERATED_BODY()
protected:
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = Touch)
float myMaxButtonPress;
public:
UPROPERTY(EditAnywhere, Category = Callback)
FButtonItemPressedSignatrue ButtonItem_OnPressed;
};
The delegate's broadcast function is then being called when the button is pressed like so:
ButtonItem_OnPressed.Broadcast();
(This function should defiantly be called because I have a debug statement that prints right before the call. Its also important to note this was all working when it was blueprint logic.)
Here is where I try to register with the delegate and how I declared the function that will be called:
WeaponMaker.h:
UFUNCTION()
void OnNextBladeButtonPressed();
WeaponMaker.cpp:
void AWeaponMaker::BeginPlay()
{
Super::BeginPlay();
TArray<USceneComponent*> weaponMakerComponents;
this->GetRootComponent()->GetChildrenComponents(true, weaponMakerComponents);
for (int componentIndex = 0; componentIndex < weaponMakerComponents.Num(); componentIndex++)
{
if (weaponMakerComponents[componentIndex]->GetName().Equals("NextBladeButton") == true)
{
myNextBladeButton = (AButtonItem*)weaponMakerComponents[componentIndex];
break;
}
}
if (myNextBladeButton != NULL)
{
myNextBladeButton->ButtonItem_OnPressed.AddDynamic(this, &AWeaponMaker::OnNextBladeButtonPressed);
}
}
I put a breakpoint and a print statement in the function OnNextBladeButtonPressed so I should immediately know when it works but its never happening. I also re-created the blueprint itself from scratch but still no luck. Sometimes on compile I get a crash due to the InvocationList being invalid but I haven't found much info on that issue either. Bottom line is, OnNextBladeButtonPressed is not getting called when it should be.
Edit: Here is where I call the broadcast function in my AButtonItem code. It seems to be getting called since i see the UE_LOG output in the console:
void AButtonItem::Tick(float deltaTime)
{
FTransform buttonWorldTransform;
FVector buttonLocalSpacePos;
FVector ownerLocalSpacePos;
FVector localDiff;
float buttonPressAmount;
if (myHasStarted == true)
{
Super::Tick(deltaTime);
if (myButtonComponent != NULL)
{
if (myPrimaryHand != NULL)
{
//Get the world space location of the button.
buttonWorldTransform = myButtonComponent->GetComponentTransform();
//Convert the location of the button and the location of the hand to local space.
buttonLocalSpacePos = buttonWorldTransform.InverseTransformPosition(myInitialOverlapPosition);
ownerLocalSpacePos = buttonWorldTransform.InverseTransformPosition(myPrimaryHand->GetControllerLocation() + (myPrimaryHand->GetControllerRotation().Vector() * myPrimaryHand->GetReachDistance()));
//Vector distance between button and hand in local space.
localDiff = ownerLocalSpacePos - buttonLocalSpacePos;
//Only interested in the z value difference.
buttonPressAmount = FMath::Clamp(FMath::Abs(localDiff.Z), 0.0f, myMaxButtonPress);
localDiff.Set(0.0f, 0.0f, buttonPressAmount);
//Set the new relative position of button based on the hand and the start button position.
myButtonComponent->SetRelativeLocation(myButtonInitialPosition - localDiff);
//UE_LOG(LogTemp, Error, TEXT("buttonPressAmount:%f"), buttonPressAmount);
if (buttonPressAmount >= myMaxButtonPress)
{
if (myHasBeenTouchedOnce == false)
{
//Fire button pressed delegate
if (ButtonItem_OnPressed.IsBound() == true)
{
ButtonItem_OnPressed.Broadcast();
AsyncTask(ENamedThreads::GameThread, [=]()
{
ButtonItem_OnPressed.Broadcast();
});
}
myHasBeenTouchedOnce = true;
myButtonComponent->SetScalarParameterValueOnMaterials("State", 1.0f);
Super::VibrateTouchingHands(EVibrationType::VE_TOUCH);
}
}
}
else
{
//Slowly reset the button position back to the initial position when not being touched.
FVector newPosition = FMath::VInterpTo(myButtonComponent->GetRelativeTransform().GetLocation(), myButtonInitialPosition, deltaTime, 10.0f);
myButtonComponent->SetRelativeLocation(newPosition);
}
}
}
}
First of all:
UPROPERTY(EditAnywhere, Category = Callback)
FButtonItemPressedSignatrue ButtonItem_OnPressed;
This should be:
UPROPERTY(BlueprintAssignable, Category = Callback)
FButtonItemPressedSignatrue ButtonItem_OnPressed;
For convenience.
Secondly the tick function may be called before begin play is executed for a number of reasons. Your even't won't be broadcasted if the game hasn't begin play yet. So to avoid just add a check in your tick function.
if(bHasBegunPlay)
{
// .. your logics ...
}
Sometimes on compile I get a crash due to the InvocationList being invalid but I haven't found much info on that issue either. Bottom line is, OnNextBladeButtonPressed is not getting called when it should be.
I don't see any issue in the code from the question. At my glance, the issue could be in different location. I would suspect that AWeaponMaker had been deleted at moment of broadcasting.

CAAnimation is deprecated in iOS 11 - need a recent answer?

Ok, I have looked EVERYWHERE and am trying here to simply extract an animation from a .dae imported into Xcode (or a .scn, whatever) so that I can run it on the model throughout my scene kit game. the problem is every way to do this that is referenced (including here Scenekit: Add animation to SCNNode from external Collada)
seems to be deprecated in iOS 11. So I have no way to animate any 3D model I put in my scene.
Right now I am able to display the model just still with this - I get the model from my dae and put it into my blank scn :
if let d = modelScene.rootNode.childNodes.first
{
theDude.node = d
theDude.setupNode() //this scales it down
}
func setupNode()
{
node.scale = SCNVector3(x: modifier, y: modifier, z: modifier)
}
//Then add to scene on tap
let clone = theDude.node.clone()
theDude.node = clone
self.sceneView.scene.rootNode.addChildNode(theDude.node)
theDude.node.position = hitPosition
This works. Trying to get it to run the animation that I added to it in Maya, however, does not. I added these extensions per Apple's example to my project:
https://developer.apple.com/library/content/samplecode/Fox/Listings/Swift_Common_SceneKitExtensions_swift.html
And was trying to do this as it says to, just with a cube as a basic test (from the above question):
func addAnim()
{
let characterScene = SCNScene(named: "art.scnassets/cubeAnimatedSkeleton.dae")!
let characterTopLevelNode = characterScene.rootNode.childNodes[0]
sceneView.scene.rootNode.addChildNode(characterTopLevelNode)
let idleAnimation = CAAnimation.animationWithSceneNamed("art.scnassets/cubeAnimatedSkeleton.dae")!
idleAnimation.usesSceneTimeBase = false
idleAnimation.repeatCount = Float.infinity
characterTopLevelNode.addAnimation(idleAnimation, forKey: "idle")
}
But with this CAAnimation.animationWithSceneNamed("art.scnassets/cubeAnimatedSkeleton.dae")! the whole thing does not work because this extension from APPLE:
extension CAAnimation {
class func animationWithSceneNamed(_ name: String) -> CAAnimation? {
var animation: CAAnimation?
if let scene = SCNScene(named: name) {
scene.rootNode.enumerateChildNodes({ (child, stop) in
if child.animationKeys.count > 0 {
animation = child.animation(forKey: child.animationKeys.first!) //ERROR
stop.initialize(to: true)
}
})
}
return animation
}
}
says that addAnimation for key was deprecated in iOS 11. Replacing that with animation = child.animationPlayer(forKey: child.animationKeys.first!) doesn't work, and I don't know what else to do.
What is wrong here?

Swift 3 - how to move sprite node when a bool is true?

Ok, I am working in Swift 3 playgrounds and need to move a sprite node to a certain point ONLY when the user's mouse is down, stopping when it's released. So far I have:
override func mouseDown(with event: NSEvent) {
mouseIsDown = true
}
override func mouseDragged(with event: NSEvent) {
}
override func mouseUp(with event: NSEvent) {
mouseIsDown = false
}
func moveGuy() {
let action = SKAction.move(to: CGPoint(x: size.width / 2,y: 200), duration: 2)
action.timingMode = .easeInEaseOut
guy.run(action)
}
//UPDATE
override func update(_ currentTime: CFTimeInterval) {
if(mouseIsDown)
{
moveGuy()
}
}
This works somewhat, the problem is only after I release the mouse (mouseIsDown is false) does the SKAction actually run (smoothly). I think this is because it is being called again and again.
Normally I would use a moveBy action in little increments, but I need my node to move to a specific point.
How can I make my node move on its way to a point only when the mouse is down?
When you call
guy.run(action)
sprite-kit will run the action on the guy until completion. You're correct, moveGuy() is being called again and again (every time the frame is update, i.e. every ~33ms assuming 30fps).
Try placing moveGuy() in mouseDown(). As soon as you click, the guy will move smoothly to his destination, but he won't stop if you stop clicking. You need to somehow stop the action. What you can do is replace
guy.run(action)
with
guy.run(action, withKey: "moveGuy")
This will associate a key with your action, that you can look up later on in mouseUp():
guy.removeAction(forKey: "moveGuy")
After this, your node will move to a point only when your mouse is down. But as you've pointed out, the node's movement is still irregular if you re-click. Try changing .easeInEaseOut to .linear. The movement will then be consistent, albeit abrupt when starting/stopping.
I highly recommend the reading documentation on SKActions to gain a better understanding of how to use them.

LWUIT List works terribly slow

I've faced with the well-known problem in LWUIT. My list component with the checkbox renderer scrolls very slow. If to test my application on emulator it runs quite smoothly (nevertheless I see CPU utilization splashes up to 60% during scroll action), but if to run it on mobile phone it takes a couple of seconds between focus movements.
There's a code of renderer:
public class CheckBoxMultiselectRenderer extends CheckBox implements ListCellRenderer {
public CheckBoxMultiselectRenderer() {
super("");
}
//override
public void repaint() {
}
public Component getListCellRendererComponent(List list, Object value,
int index,boolean isSelected) {
Location loc = (Location)value;
setText(loc.getLocationName());
setFocus(isSelected);
setSelected(loc.isSelected());
return this;
}
public Component getListFocusComponent(List list) {
setText("");
setFocus(true);
getStyle().setBgTransparency(Consts.BG_TRANSPARENCY);
return this;
}
}
that's the code of my form containing the list:
protected void createMarkup() {
Form form = getForm();
form.setLayout(new BorderLayout());
form.setScrollable(false);
Label title = new Label("Choose location zone:");
title.getStyle().setMargin(5, 5, 0, 0);
title.getStyle().setBgTransparency(Consts.BG_TRANSPARENCY);
title.setAlignment(Component.CENTER);
form.addComponent(BorderLayout.NORTH, title);
list = new List(StateKeeper.getLocationsAsList());
list.setFixedSelection(List.FIXED_NONE_CYCLIC);
// list.setSmoothScrolling(true);
list.getStyle().setBgTransparency(0);
list.setListCellRenderer(new CheckBoxMultiselectRenderer());
list.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent ae){
// List l = (List)ae.getSource();
// l.requestFocus();
// l.setHandlesInput(true);
Location selItem = (Location)list.getSelectedItem();
selItem.setSelected(!selItem.isSelected());
}
});
form.addComponent(BorderLayout.CENTER, list);
}
I would be very thankful for any help!
We must be so carefull building lwuit List. If we have made something wrong they can work worse than expected. I recommend you to take a look on this
LWUIT Blog ListRender
You can also rewrite your paint method. You list's speed will be increased.