Spatial Anchor with Urho on HoloLens - hololens

Does anybody know how to use Spatial Anchors with Urho? I've looked at all the samples, didn't find anything. Nothing in the documentation either. I tried using regular Holographic API:
var store = await SpatialAnchorManager.RequestStoreAsync();
var anchors = store.GetAllSavedAnchors();
store.TrySave("myanchor", SpatialAnchor.TryCreateRelativeTo(???SpatialCoordinateSystem???));
but I don't know where to get the Spatial Coordinate System from.

You can create spatial anchors like this
var anchor = SpatialAnchor.TryCreateRelativeTo(UrhoAppView.Current.ReferenceFrame.CoordinateSystem, new System.Numerics.Vector3(x, y, -z));
store.TrySave("anchorname", anchor);
Note that Urho has a left-handed coordinate system while HoloLens API has a right-handed coordinate system hence the minus z.
You can map an anchor to the current system like this:
var matrix = store["anchorname"].CoordinateSystem.TryGetTransformTo(UrhoAppView.Current.ReferenceFrame.CoordinateSystem);
if (matrix.HasValue)
{
System.Numerics.Vector3 scale;
System.Numerics.Quaternion rotation;
System.Numerics.Vector3 translation;
System.Numerics.Matrix4x4.Decompose(matrix.Value, out scale, out rotation, out translation);
var q = new Quaternion(rotation.X, rotation.Y, rotation.Z, rotation.W);
var v = new Vector3(translation.X, translation.Y, -translation.Z);// -Z Right-handed to left-handed
}

Related

SpriteKit How to add laser beam and resize it at collision point

I'm developing my first game with SpriteKit and I need to shoot a laser beam. I don't know how to do this since I don't know the size of the laser sprite, does it have to be with size of the screen height and crop the image when a collision is detected? can anyone point me to the right directions please? Have no idea about this XD
Thanks for your comments :D
This could be done by line-of-sight detection system described here in the section Searching for physics bodies :
Useful method would be enumerateBodiesAlongRayStart:end:usingBlock: from SKPhysicsWorld class which enumerates all the physics bodies in the scene that intersect a ray.
Basically you have to set start point and search for end point using the method above.When you know where is the intersection point(end point of laser beam) you can easily draw it.
This is a way late response, but I've got a really nice solution. Here's what it looks like (Swift 3):
In my code I'm calling this when I rotate the node I want the laser to shoot out of:
self.laser = SKShapeNode()
laser.lineWidth = 6
laser.glowWidth = 8
laser.strokeColor = .red
let _ = isTargetVisibleAtAngle(startPoint: startPoint, angle: selectedBeam!.zRotation + (CGFloat.pi / 2), distance: frame.size.height)
And this is the method. Obviously you put in whatever angle you want. The "foundOne" thing is so that it stops on the first object if that ray crosses through multiple targets
func isTargetVisibleAtAngle(startPoint: CGPoint, angle: CGFloat, distance: CGFloat) -> Bool {
let rayStart = startPoint
let rayEnd = CGPoint(x: rayStart.x + distance * cos(angle),
y: rayStart.y + distance * sin(angle))
let path = CGMutablePath()
path.move(to: rayStart)
path.addLine(to: rayEnd)
laser.path = path
var foundOne = false
let _ = physicsWorld.enumerateBodies(alongRayStart: rayStart, end: rayEnd) { (body, point, vector, stop) in
if !foundOne {
foundOne = true
let p = CGMutablePath()
p.move(to: rayStart)
p.addLine(to: point)
self.laser.path = p
}
}
return false
}

two meshes, same texture, different offset?

Using three.js, I'm working on a web page to display a flip cube (a.k.a. magic cube; see e.g. the video on this page).
On a flip cube, there are typically images that are spread out across multiple pieces of the cube. For example, the boat image shown above is spread across the faces of four cubelets. In three.js terms, there are multiple meshes that need to use the same image for their material texture, but each at a different offset.
As far as I understand it, in three.js, offset is a property of a texture, not of a material or a mesh. Therefore, it would appear that you cannot have a single texture that is used at a different offset in two different places.
So does that mean that in order to have different parts of the boat image shown on four different faces, I have to create four separate textures, meaning that we load the boat image into memory four times? I'm hoping that's not the case.
Here's a relevant piece of the code:
// create an array with the textures
var textureArray = [];
var texNames = ['boat', 'camels', 'elephants', 'hippo',
'natpark', 'ostrich', 'coatofarms-w', 'kenyamap-w', 'nairobi-w'];
texNames.map(function(texName) {
textureArray.push(THREE.ImageUtils.loadTexture(
'images/256/' + texName + '.jpg' ));
});
// Create a material for each texture.
for (var x=0; x <= 1; x++) {
for (var y=0; y <= 1; y++) {
for (var z=0; z <= 1; z++) {
var materialArray = [];
textureArray.map(function(tex) {
// Learned: cannot set this offset for one material,
// without it affecting all materials that use this texture.
tex.offset.x = x * 0.2;
tex.offset.y = y * 0.2;
materialArray.push(new THREE.MeshBasicMaterial( { map: tex }));
});
var cubeMaterial = new THREE.MeshFaceMaterial(materialArray.slice(0, 6));
var cube = new THREE.Mesh( cubeGeom, cubeMaterial );
cube.position.set(x * 50 - 25, y * 50 - 25, z * 50 - 25);
scene.add(cube);
}
}
}
If you look at it on http://www.huttar.net/lars-kathy/tmp/flipcube.html, you'll see that all the texture images are displayed offset by the same amount on each cubelet face, even though they are set to different offsets on different cubelets. This seems to confirm that you can't have different uses of the same texture with different offsets.
How can I get different meshes to use the same texture at different offsets, so I don't have to load the same image multiple times into multiple textures?
What you say is true. Instead of adjusting the texture offsets, adjust the face vertex UVs of the geometry.
EDIT: There is another solution more in line with what you want to do. You can clone a texture like so:
var tex = new THREE.Texture.clone();
Cloning a texture will result in the loaded image being reused, and the new texture can have it's own offsets. Do not try to clone the texture until the image loads, however.
With this alternate approach, you do not have to adjust UVs, and you do not have to load an image more than once.
three.js r.58

How to avoid the overlapping of text elements on the TreeMap when child elements are opened in D3.js?

I created a Tree in D3.js based on Mike Bostock's Node-link Tree. The problem I have and that I also see in Mike's Tree is that the text label overlap/underlap the circle nodes when there isn't enough space rather than extend the links to leave some space.
As a new user I'm not allowed to upload images, so here is a link to Mike's Tree where you can see the labels of the preceding nodes overlapping the following nodes.
I tried various things to fix the problem by detecting the pixel length of the text with:
d3.select('.nodeText').node().getComputedTextLength();
However this only works after I rendered the page when I need the length of the longest text item before I render.
Getting the longest text item before I render with:
nodes = tree.nodes(root).reverse();
var longest = nodes.reduce(function (a, b) {
return a.label.length > b.label.length ? a : b;
});
node = vis.selectAll('g.node').data(nodes, function(d, i){
return d.id || (d.id = ++i);
});
nodes.forEach(function(d) {
d.y = (longest.label.length + 200);
});
only returns the string length, while using
d.y = (d.depth * 200);
makes every link a static length and doesn't resize as beautiful when new nodes get opened or closed.
Is there a way to avoid this overlapping? If so, what would be the best way to do this and to keep the dynamic structure of the tree?
There are 3 possible solutions that I can come up with but aren't that straightforward:
Detecting label length and using an ellipsis where it overruns child nodes. (which would make the labels less readable)
scaling the layout dynamically by detecting the label length and telling the links to adjust accordingly. (which would be best but seems really difficult
scale the svg element and use a scroll bar when the labels start to run over. (not sure this is possible as I have been working on the assumption that the SVG needs to have a set height and width).
So the following approach can give different levels of the layout different "heights". You have to take care that with a radial layout you risk not having enough spread for small circles to fan your text without overlaps, but let's ignore that for now.
The key is to realize that the tree layout simply maps things to an arbitrary space of width and height and that the diagonal projection maps width (x) to angle and height (y) to radius. Moreover the radius is a simple function of the depth of the tree.
So here is a way to reassign the depths based on the text lengths:
First of all, I use the following (jQuery) to compute maximum text sizes for:
var computeMaxTextSize = function(data, fontSize, fontName){
var maxH = 0, maxW = 0;
var div = document.createElement('div');
document.body.appendChild(div);
$(div).css({
position: 'absolute',
left: -1000,
top: -1000,
display: 'none',
margin:0,
padding:0
});
$(div).css("font", fontSize + 'px '+fontName);
data.forEach(function(d) {
$(div).html(d);
maxH = Math.max(maxH, $(div).outerHeight());
maxW = Math.max(maxW, $(div).outerWidth());
});
$(div).remove();
return {maxH: maxH, maxW: maxW};
}
Now I will recursively build an array with an array of strings per level:
var allStrings = [[]];
var childStrings = function(level, n) {
var a = allStrings[level];
a.push(n.name);
if(n.children && n.children.length > 0) {
if(!allStrings[level+1]) {
allStrings[level+1] = [];
}
n.children.forEach(function(d) {
childStrings(level + 1, d);
});
}
};
childStrings(0, root);
And then compute the maximum text length per level.
var maxLevelSizes = [];
allStrings.forEach(function(d, i) {
maxLevelSizes.push(computeMaxTextSize(allStrings[i], '10', 'sans-serif'));
});
Then I compute the total text width for all the levels (adding spacing for the little circle icons and some padding to make it look nice). This will be the radius of the final layout. Note that I will use this same padding amount again later on.
var padding = 25; // Width of the blue circle plus some spacing
var totalRadius = d3.sum(maxLevelSizes, function(d) { return d.maxW + padding});
var diameter = totalRadius * 2; // was 960;
var tree = d3.layout.tree()
.size([360, totalRadius])
.separation(function(a, b) { return (a.parent == b.parent ? 1 : 2) / a.depth; });
Now we can call the layout as usual. There is one last piece: to figure out the radius for the different levels we will need a cumulative sum of the radii of the previous levels. Once we have that we simply assign the new radii to the computed nodes.
// Compute cummulative sums - these will be the ring radii
var newDepths = maxLevelSizes.reduce(function(prev, curr, index) {
prev.push(prev[index] + curr.maxW + padding);
return prev;
},[0]);
var nodes = tree.nodes(root);
// Assign new radius based on depth
nodes.forEach(function(d) {
d.y = newDepths[d.depth];
});
Eh voila! This is maybe not the cleanest solution, and perhaps does not address every concern, but it should get you started. Have fun!

Raphael -- object rotation at arbitrary position

I'm using Raphael_2.01 and would like to rotate an object at arbitrary position.
(WindowsXP, Firefox3.6)
example: http://uproda11.2ch-library.com/326446b6u/11326446.png
This rectangle (rect0) rotates thirty degrees at its lower right point.
The parameters are:
var rectX = rect0.getBBox().x;
var rectY = rect0.getBBox().y;
var rectW = rect0.getBBox().width;
var rectH = rect0.getBBox().height;
var rot = 30;// rotation
var rotX, rotY;// arbitrary position
What code should I use ? I can't image suitable method.
thanks,
If I understand the question correctly, it's rect0.rotate(30, rotX, rotY);.

Using ShowTextAtPoint the displayed text is flipped

I'm using the ShowTextAtPoint method of CGContext to display a Text in a view, but it is displayed in flip mode, anyone knows how to solve this problem ?
Here is the code I use :
ctx.SelectFont("Arial", 16f, CGTextEncoding.MacRoman);
ctx.SetRGBFillColor(0f, 0f, 1f, 1f);
ctx.SetTextDrawingMode(CGTextDrawingMode.Fill);
ctx.ShowTextAtPoint(centerX, centerY, text);
You can manipulate the current transformation matrix on the graphics context to flip it using ScaleCTM and TranslateCTM.
According to the Quartz 2D Programming Guide - Text:
In iOS, you must apply a transform to the current graphics context in order for the text to be oriented as shown in Figure 16-1. This transform inverts the y-axis and translates the origin point to the bottom of the screen. Listing 16-2 shows you how to apply such transformations in the drawRect: method of an iOS view. This method then calls the same MyDrawText method from Listing 16-1 to achieve the same results.
The way this looks in MonoTouch:
public void DrawText(string text, float x, float y)
{
// the incomming coordinates are origin top left
y = Bounds.Height-y;
// push context
CGContext c = UIGraphics.GetCurrentContext();
c.SaveState();
// This technique requires inversion of the screen coordinates
// for ShowTextAtPoint
c.TranslateCTM(0, Bounds.Height);
c.ScaleCTM(1,-1);
// for debug purposes, draw crosshairs at the proper location
DrawMarker(x,y);
// Set the font drawing parameters
c.SelectFont("Helvetica-Bold", 12.0f, CGTextEncoding.MacRoman);
c.SetTextDrawingMode(CGTextDrawingMode.Fill);
c.SetFillColor(1,1,1,1);
// Draw the text
c.ShowTextAtPoint( x, y, text );
// Restore context
c.RestoreState();
}
A small utility function to draw crosshairs at the desired point:
public void DrawMarker(float x, float y)
{
float SZ = 20;
CGContext c = UIGraphics.GetCurrentContext();
c.BeginPath();
c.AddLines( new [] { new PointF(x-SZ,y), new PointF(x+SZ,y) });
c.AddLines( new [] { new PointF(x,y-SZ), new PointF(x,y+SZ) });
c.StrokePath();
}

Resources