I'm writing a driver to handle touch events from a Planar touch screen (in OSX) using Apple's IOKit tools. The driver is able to receive x and y coordinates, but I'm having trouble figuring out which finger the coordinates belong to.
In my callback function, I'm querying the most recent value's parent to determine the finger ID, but the value is always the most recent finger – so 3 if there are 3 fingers down, 2 if there are 2 fingers down, etc., etc. Here's what callback looks like:
void touchCallback(void *context, IOReturn result, void *sender, IOHIDValueRef value) {
IOHIDElementRef element = IOHIDValueGetElement(value);
IOHIDDeviceRef device = IOHIDElementGetDevice(element);
IOHIDElementRef parent = IOHIDElementGetParent(element);
IOHIDElementRef parent2 = IOHIDElementGetParent(parent);
CFArrayRef parentChildren = IOHIDElementGetChildren(parent2);
IOHIDValueRef fingerVal;
IOHIDDeviceGetValue(device, (IOHIDElementRef)CFArrayGetValueAtIndex(parentChildren, 5), &fingerVal);
long fingerID = IOHIDValueGetIntegerValue(fingerVal);
}
Is there another recommended approach for determining which finger the x and y coordinates belong to?
Similarly, are there any recommended practices for figuring out which finger is being released?
I'm receiving events that indicate a finger has been lifted, but the numbers are inconsistent – sometimes it'll report the same finger ID 2x, other times it won't report anything. Is there a 'frame'-based approach to testing if a fingers is still down?
Thanks++ for any advice!
Related
I'm a new in Unity and making my first 2D game. I seen several topics on this forum in this issue, but I didn't found the solution.
So I have a lovely shooting animation and the bullet generation. My problem, I have to generate the bullet somewhere at the middle of the animation, but the character shoots the bullet and the animation at the same time, which killing the UX :)
I attached an image, about the issue, this is the moment, when the bullet should be initialized, but as you can see it's already on it's way.
Please find my code:
The GameManager update method calls the attackEnemy function:
public void Awake(){
animator = GetComponent ();
animator.SetTrigger ("enemyIdle");
}
//if the enemy pass this point, they stop shooting, and just go off the scren
private float shootingStopLimit = -6f;
public override void attackPlayer(){
//animator.SetTrigger ("enemyIdle");
if (!isAttacking && gameObject.transform.position.y > shootingStopLimit) {
isAttacking = true;
animator.SetTrigger("enemyShoot");
StartCoroutine(doWait());
gameObject.GetComponentInChildren ().fireBullet ();
StartCoroutine (Reload ());
}
}
private IEnumerator doWait(){
yield return new WaitForSeconds(5);
}
private IEnumerator Reload(){
animator.SetTrigger ("enemyIdle");
int reloadTime = Random.Range (4,7);
yield return new WaitForSeconds(reloadTime);
isAttacking = false;
}......
My questions:
- How can I sync the animation and the bullet generation ?
Why not the doWait() works ? :)
Is it okay to call the attackPlayer method from the GameManager update ?
The enemies are flynig from the right side of the screen to the left, when they reach the most right side of the screen, they became visible to the user. I don't know why, but they to a shooting animation (no bullet generation happen )first, only after it they do the idle. Any idea why ?
Thanks,
K
I would suggest checking out animation events. Using animation events, you can call a method to instantiate your bullet.
To use Mecanim Animation Events you need to write the name of the function you want to call at the selected frame in the "Function" area of the "Edit Animation Event" window.
The other boxes are for any variables that you want to pass to that function to trigger whatever you have in mind.
Triggering/blending between different animations can be done in many different ways. The event area is more for other things that you want to trigger that are not related to animation (e.g. audio, particle fx, etc).
I'm a beginner using Arduino with a Teensy 3.2 board and programming it as a usb keyboard.
I have two 4 button membrane switches. Their button contacts are on pins 1-8, and the 9th pin holds a soldered together wire of both membrane switches' "ground" line or whatever it's true name is; the line that completes the circuit.
Basically when you press the buttons they are supposed to simply type "a, b, c..." respectively. I've been told I need to use a matrix for this.
I'm looking for an example of how to code a keyboard matrix that effectively supports a one row/9 column line (or vice versa?) I've been unable to find that solution online.
All I have so far is this code which, when the button on the second pin is pressed, sends tons of "AAAAAAAAAAAAAAAA" keystrokes.
void setup() {
// make pin 2 an input and turn on the
// pullup resistor so it goes high unless
// connected to ground:
pinMode(2, INPUT_PULLUP);
Keyboard.begin();
}
void loop() {
//if the button is pressed
if(digitalRead(2)==LOW){
//Send an ASCII 'A',
Keyboard.write(65);
}
}
Would anyone be able to help?
First of all, a 1-row keypad is NOT a matrix. Or better, technically it can be considered a matrix but... A matrix keypad is something like this:
You see? In order to scan this you have to
Pull Row1 to ground, while leaving rows 2-4 floating
Read the values of Col1-4. These are the values of switches 1-4
Pull Row2 to ground, while leaving rows 1 and 3-4 floating
Read the values of Col1-4. These are the values of switches 5-8
And so on, for all the rows
As for the other problem, you are printing an A when the button is held low. What you want to achieve is to print A only on the falling edge of the pin (ideally once per pressure), so
char currValue = digitalRead(2);
if((currValue==LOW) && (oldValue==HIGH))
{
//Send an ASCII 'A',
Keyboard.write(65);
}
oldValue = currValue;
Of course you need to declare oldValue outside the loop function and initialize it to HIGH in the main.
With this code you won't receive tons of 'A's, but however you will see something like 5-10 'A's every time you press the button. Why? Because of the bouncing of the button. That's what debouncing techniques are for!
I suggest you to look at the class Bounce2 to get an easy to use class for your button. IF you prefer some code, I wrote this small code for another question:
#define CHECK_EVERY_MS 20
#define MIN_STABLE_VALS 5
unsigned long previousMillis;
char stableVals;
char buttonPressed;
...
void loop() {
if ((millis() - previousMillis) > CHECK_EVERY_MS)
{
previousMillis += CHECK_EVERY_MS;
if (digitalRead(2) != buttonPressed)
{
stableVals++;
if (stableVals >= MIN_STABLE_VALS)
{
buttonPressed = !buttonPressed;
stableVals = 0;
if (buttonPressed)
{
//Send an ASCII 'A',
Keyboard.write(65);
}
}
}
else
stableVals = 0;
}
}
In this case there is no need to check for the previous value, since the function already has a point reached only when the state changes.
If you have to use this for more buttons, however, you will have to duplicate the whole code (and also to use more stableVals variables). That's why I suggsted you to use the Bounce2 class (it does something like this but, since it is all wrapped inside a class, you won't need to bother about variables).
I am working on migrating the drawing code of an application from GDI/GDI+ to Direct2D. So far things have been going well - however, while testing the new code, I have noticed some bizarre performance. The flow of execution I have been investigating is as follows (I have done my best to remove irrelevant code):
Create D2D Factory (on creation of app)
HRESULT hr = S_OK;
hr = D2D1CreateFactory(D2D1_FACTORY_TYPE_MULTI_THREADED, &m_pD2DFactory);
if (hr == S_FALSE) {
ASSERT(FALSE);
throw Exception(CExtString(_T("Failed to create Direct2D factory")));
}
OnDraw Callback
HWND hwnd = GetSafeHwnd();
RECT rc;
GetClientRect(&rc);
D2D1_SIZE_U size = D2D1::SizeU(rc.right - rc.left, rc.bottom - rc.top);
// Create a render target if it has been destroyed
if (!m_pRT) {
D2D1_RENDER_TARGET_PROPERTIES props = D2D1::RenderTargetProperties(
D2D1_RENDER_TARGET_TYPE_DEFAULT,
D2D1::PixelFormat(
DXGI_FORMAT_B8G8R8A8_UNORM,
D2D1_ALPHA_MODE_IGNORE),
0,
0,
D2D1_RENDER_TARGET_USAGE_NONE,
D2D1_FEATURE_LEVEL_DEFAULT);
GetD2DFactory()->CreateHwndRenderTarget(props,
D2D1::HwndRenderTargetProperties(hwnd, size),
&m_pRT);
}
m_pRT->Resize(size);
m_pRT->BeginDraw();
// Begin drawing the layers, given the
// transformation matrix and some geometric information
Draw(m_pRT, matrixD2D, rectClipWorld, rectClipDP);
HRESULT hr = m_pRT->EndDraw();
if (hr == D2DERR_RECREATE_TARGET) {
SafeRelease(m_pRT);
}
The contents of the Draw method
The draw method does a lot of fluff that is largely irrelevant to this test (as I have turned all extraneous layers off), but it eventually draws a layer that executes this method several thousand times:
void DrawStringWithEffects(ID2D1RenderTarget* m_pRT, const CString& text, const D2D1_POINT_2F& point, const COLORREF rgbFore, const COLORREF rgbBack, IDWriteTextFormat* pfont) {
// The text will be vertically centered around point.y, with point.x on the left hand side
// Create a TextLayout for the string
IDWriteTextLayout* textLayout = NULL;
GetDWriteFactory()->CreateTextLayout(text,
text.GetLength(),
pfont,
std::numeric_limits<float>::infinity(),
std::numeric_limits<float>::infinity(),
&textLayout);
DWRITE_TEXT_METRICS metrics = {0};
textLayout->GetMetrics(&metrics);
D2D1_RECT_F rect = D2D1::RectF(point.x, point.y - metrics.height/2, point.x + metrics.width, point.y + metrics.height/2);
D2D1_POINT_2F pointDraw = point;
pointDraw.y -= metrics.height/2;
ID2D1SolidColorBrush* brush = NULL;
m_pRT->CreateSolidColorBrush(ColorD2DFromCOLORREF(rgbBack), &brush);
m_pRT->FillRectangle(rect, brush);
// ^^ this is sometimes very slow!
brush->SetColor(ColorD2DFromCOLORREF(rgbFore));
m_pRT->DrawTextLayout(pointDraw, textLayout, brush, D2D1_DRAW_TEXT_OPTIONS_NONE);
// ^^ this is also sometimes very slow!
SafeRelease(&brush);
SafeRelease(&textLayout);
The vast majority of the time, the Direct2D calls are executing ~3-4 times faster than the GDI+ equivalents, which is great (generally 0.1ms compared to ~0.35ms). For some reason, though, the function calls will occasionally stall for a long period of time - upwards of 200ms combined. The offending calls are straight from the Direct2D API - FillRectangle and DrawTextLayout. Strangely, these stalls appear in the same location every time I run the application - the 73rd occurrence of the loop, then the 218th, then the 290th and so on (there is somewhat of a pattern in the differences, alternating between every ~73rd and every ~145th cycle). This is independent of the data that it draws (when I told it to skip drawing the 73rd cycle, the next cycle simply becomes the 73rd and thus stalls).
I thought this may be a GPU/CPU communication issue, so I set the render target (I am using an HWnd target) to software mode (D2D1_RENDER_TARGET_TYPE_SOFTWARE), and the results were even more strange. The stall times dropped from ~200ms to ~20ms (still not great, but hey), but there were two instances that stalled for over 2500ms! (These two, like the rest of the stalls, are completely reproducible in terms of being the n'th API call).
This is rather frustrating, as 99% of the loop is several times faster than the old implementation, but the (less than) 1% remaining hang for an abnormally long time.
To any Direct2D experts out there - what type of problem might this stalling be a symptom of? What, in general, could be causing this disconnect between my code and what D2D is doing in the background?
Direct2D buffers drawing commands (presumably to optimize them). You can't look at the performance of an individual drawing command, you must look at the total time between BeginDraw() and EndDraw(). If you want to force each drawing command to execute immediately, you must follow each one with a call to Flush(). That's probably a bad idea for performance though.
https://msdn.microsoft.com/en-us/library/windows/desktop/dd371768(v=vs.85).aspx
After BeginDraw is called, a render target will normally build up a
batch of rendering commands, but defer processing of these commands
until either an internal buffer is full, the Flush method is called,
or until EndDraw is called.
I'm using the JPointCloud sample app, and modifying it a little bit:
In JPointCloud.java : SetUpExtrinsics(), I added:
TangoPoseData depth2devicePose = new TangoPoseData();
framePair.baseFrame = TangoPoseData.COORDINATE_FRAME_DEVICE;
framePair.targetFrame = TangoPoseData.COORDINATE_FRAME_CAMERA_DEPTH;
try {
depth2devicePose = mTango.getPoseAtTime(0.0, framePair);
} catch (TangoErrorException e) {
Toast.makeText(getApplicationContext(), R.string.TangoError,
Toast.LENGTH_SHORT).show();
The application crashes when reaching the line:
depth2devicePose = mTango.getPoseAtTime(0.0, framePair);
I tried with other combinations of frame, but each time COORDINATE_FRAME_CAMERA_DEPTH is included, the app crashes.
Did I forget something ? Maybe to ask some kind of special permission for the depth camera ?
It indeed crashes on me as well.
However, according to the Java pointcloud example code (extrinsic query part), the correct way of querying the DEPTH_CAMERA w.r.t(with respect to) DEVICE transformation is using 'the inverse of DEVICE w.r.t IMU' multiply 'CAMAER w.r.t IMU', which is:
deive_T_camera = inverse(imu_T_device) * imu_T_camera
Also, note that the color camera, depth camera and camera are the same camera on the hardware level, so they actually share the same extrinsic.
Hope this helps.
Edit: the crashes actually throw an com.google.atap.tangoservice.TangoInvalidException. This might just be a frame pair not supported from API level, as mentioned before, the suggested way would be using other two matrices to compose the desired matrix in this case..
I am trying to write some code that will allow the user to draw on the touch screen.
When using either GestureService or ManipulationStarted/Delta, there's a "pause" that occurs when the user starts moving their finger - only when the finger is far enough from the point in which it started, only then do you start getting ManipulationDelta events (and like I said, same deal is true for GestureService).
What can I do to avoid this threshold? It really does not work well with drawing code.
Just blogged about it as I have come across similar questions on AppHub Forum.
https://invokeit.wordpress.com/2012/04/27/high-performance-touch-interface-wpdev-wp7dev/
Manipulation Delta and Gesture services are high level touch interfaces. If you want performance, consider using low level interfaces: Touch and an event called TouchReported. I tend to use them mostly (for drawing / position detection) in many of my projects
The event you want to plug in to detech touch is
Touch.FrameReported += Touch_FrameReported;
You can do this in Loaded event. Here's the implementation of the Touch_FrameReported handler. WorkArea is Canvas in this. I have also used this in conjugation with WritableBitmap
private void Touch_FrameReported(object sender, TouchFrameEventArgs e)
{
try
{
// Determine if finger / mouse is down
point = e.GetPrimaryTouchPoint(this.workArea);
if (point.Position.X < 0 || point.Position.Y < 0)
return;
if (point.Position.X > this.workArea.Width || point.Position.Y > this.workArea.Height)
return;
if (this.lbLetter.SelectedIndex == -1)
return;
switch (point.Action)
{
case TouchAction.Down:
draw = true;
old_point = point;
goto default;
case TouchAction.Up:
draw = false;
break;
default:
Draw();
break;
}
}
catch
{
MessageBox.Show("Application encountered error processing last request.");
}
}
This works lot better than high level interfaces.