Im trying to synchronize Potree camera with Cesium camera, like in this briliant example, but in oposite way (moves of Cesium camera control Potree camera).
function syncPotreeWithCesium() {
//lets get camera position and direction in Cesium
var newCamCoordinatesWC = cesiumViewer.scene.camera.positionWC;
var newDirectionCoordinatesWC = cesiumViewer.scene.camera.directionWC;
//as potree works in declaredEPSG, lets transform Cesium WC to declaredEPSG
var positionCartographicWC = Cesium.Ellipsoid.WGS84.cartesianToCartographic(newCamCoordinatesWC);
var directionCartographicWC = Cesium.Ellipsoid.WGS84.cartesianToCartographic(newDirectionCoordinatesWC);
var camPosXY = proj4(declaredEPSG,[(positionCartographicWC.longitude * (180/Math.PI)),(positionCartographicWC.latitude * (180/Math.PI))]);
var camDirXY = proj4(declaredEPSG,[(directionCartographicWC.longitude * (180/Math.PI)),(directionCartographicWC.latitude * (180/Math.PI))]);
//set Potree camera coordinates and direciton
potreeViewer.scene.view.position.set(camPosXY[0], camPosXY[1], positionCartographicWC.height);
potreeViewer.scene.view.lookAt(camDirXY[0], camDirXY[1], directionCartographicWC.height);
//"aspect" part from mentioned example seems to be applicable almost 1:1
var cesiumAspect = cesiumViewer.scene.camera.aspectRatio;
if(cesiumAspect < 1){
let fovy = Math.PI * (cesiumViewer.camera.frustum.fov / 180);
potreeViewer.scene.getActiveCamera().fov = fovy;
}else{
let fovy = Math.PI * (cesiumViewer.camera.frustum.fov / 180);
let fovx = Math.atan(Math.tan(0.5 * fovy) * cesiumAspect) * 2
potreeViewer.scene.getActiveCamera().fov = fovx;
}
//not sure if this part is needed in this simplified example
let camera = potreeViewer.scene.getActiveCamera();
camera.updateProjectionMatrix();
}
cesiumViewer.camera.changed.addEventListener(syncPotreeWithCesium);
`
As a result point cloud "dances" around desirable place in closeup, and gets even worse when zoomed out.
Except position and direction Cesium also needs „up” vector to set camera with this method, like here:
cesiumViewer.camera.setView({
destination : cameraPositon,
orientation : {
direction : dirVector,
up : upVector
}
And I do not see such setting in Potree camera/view settings. Is that causing a problem ?
Or am I missing more pieces to do it properly ??? Any help would be appreciated.
As documentation of Three.js said, after changing the position of the camera, we must call the updateProjectionMatrix() method.
I'm doing the same. But it gives me an error like this:
TypeError: object.updateWorldMatrix is not a function
at Box3.expandByObject (three.module.js:6329)
at Box3.setFromObject (three.module.js:6233)
at index.js:66
at GLTFLoader.js:147
at GLTFLoader.js:1639
My goal is to put my loaded GLTF object, in the center of the screen.
And this is the code I'm using for it:
this.gltfLoader.load("/corolla.gltf", (object) => {
const box = new THREE.Box3().setFromObject(object);
const size = box.getSize(new THREE.Vector3()).length();
const center = box.getCenter(new THREE.Vector3());
// reset OrbitControl
this.controls.reset();
object.position.x += (object.position.x - center.x);
object.position.y += (object.position.y - center.y);
object.position.z += (object.position.z - center.z);
this.controls.maxDistance = size * 10;
this.camera.near = size / 100;
this.camera.far = size * 100;
this.camera.updateProjectionMatrix();
this.camera.position.copy(center);
this.camera.position.x += size / 2.0;
this.camera.position.y += size / 5.0;
this.camera.position.z += size / 2.0;
this.camera.lookAt(center);
this.gltf = object.scene;
this.scene.add(this.gltf);
},
this.manageLoading,
this.gltfLoadErr);
For the record, I'm using the last version of Three.js, it's 0.110.0;
It looks like the errors is occurring here:
const box = new THREE.Box3().setFromObject(object);
Where object is the object coming back from the call to GLTFLoader.load.
According to the docs, object is not an Object3D (which is what Box3.setFromObject expects).
Instead, object is a JSON structure containing information about the GLTF data. The three.js example suggests object.scene would be a renderable entity (if it exists).
Take a look at the code for the GLTFLoader example, here. Compare it against your implementation. You can also debug your code to see exactly what is object contains. Once you have a handle on that, if you're still having problems, come back and ask more questions!
Short solution:
var hollowCylinderGeom = new THREE.LatheBufferGeometry([
new THREE.Vector2(1, 0),
new THREE.Vector2(2, 0),
new THREE.Vector2(2, 2),
new THREE.Vector2(1, 2),
new THREE.Vector2(1, 0)
], 90).toNonIndexed();
var mesh = new THREE.Mesh(hollowCylinderGeom);
console.log(new THREE.Box3().setFromObject(mesh));
I can't find out why my transformations are not being applied to a UIImageView in Xamarin iOS.
Here's the code:
CGAffineTransform transform = new CGAffineTransform();
transform.Rotate((float)Math.PI / 2);
transform.Scale(0.8f, 0.8f);
this.imageViewOverlay = new UIImageView
{
ContentMode = UIViewContentMode.Center,
BackgroundColor = UIColor.Clear,
Opaque = false,
Frame = new CGRect(0,0,this.View.Bounds.Width, this.View.Bounds.Height),
Transform = transform
};
The way I was doing it before used to be like
Transform = CGAffineTransform.MakeRotation((float)Math.PI / 2)
But unfortunately when you want to use it twice, the second one is clearing the transformation before.
I'm using
Xamarin.iOS:
Version: 8.6.0.41 (Business Edition)
Operating System:
Mac OS X 10.10.3
XCode: Version 6.3.1 (6D1002)
Thanks !
Your original CGAffineTransform is empty (all 00), default for a struct, and not an identity transform, on top of which you can construct something. IOW that makes all subsequent calls (math ops) return an empty one.
You can either start with a non-empty transform, e.g.
var transform = CGAffineTransform.MakeRotation((float)Math.PI / 2);
transform.Scale(0.8f, 0.8f);
or you can start with an identity transform, e.g.
var transform = CGAffineTransform.MakeIdentity ();
transform.Rotate ((nfloat) Math.PI / 2);
transform.Scale ((nfloat) 0.8f, (nfloat) 0.8f);
I have created a view and in my draw rect method I create paths depending on what a user does with sliders. Using standard colors , everything works and looks very nice. I am trying to follow a code snippet from apple that shows how to draw patterns into a rect at this link:
Apple Drawing Guide
The example shows how to create a function callback with the pattern desired and then an additional method call to draw the rect. If I call the code as it is written from my rect it will draw my pattern as I would expect, however, I do not want to fill my rect , I want to fill a specified path in the rect. If I change the call in the drawing method from CGContextFillRect to CGContextFillPath, it doesn't work. I'm sure there is something I am overlooking to modify this code to get it to do what I want.
My callback pattern is a simple checkerboard:
code:
// Call Back function for Graphics Pattern
#define PATTERN_SIZE 10
void patternSpec(void *info , CGContextRef pContext){
NSLog(#"patternSpec Callback Called");
CGFloat subUnit = PATTERN_SIZE / 2;
CGRect square1 = {{0,0}, {subUnit, subUnit}},
square2 = {{subUnit, subUnit}, {subUnit, subUnit}},
square3 = {{0 , subUnit}, {subUnit, subUnit}},
square4 = {{subUnit , 0}, {subUnit, subUnit}};
CGContextSetRGBFillColor(pContext, 1.0, 0.0, 0.0, 1.0 );
CGContextFillRect(pContext, square1);
CGContextSetRGBFillColor(pContext, 1.0, 0.0, 0.0, 1.0 );
CGContextFillRect(pContext, square2);
CGContextSetRGBFillColor(pContext, 0.0, 0.0, 0.0, 1.0 );
CGContextFillRect(pContext, square3);
CGContextSetRGBFillColor(pContext, 0.0, 0.0, 0.0, 1.0 );
CGContextFillRect(pContext, square4);
}
// Method that draws the pattern
static void drawPattern (CGContextRef myContext)
{
NSLog(#"drawPattern Called ");
CGPatternRef pattern;
CGColorSpaceRef patternSpace;
CGFloat alpha = 1.0;
//width, height;
static const CGPatternCallbacks callbacks = {0, &patternSpec, NULL};
CGContextSaveGState (myContext);
patternSpace = CGColorSpaceCreatePattern (NULL);// 6
CGContextSetFillColorSpace (myContext, patternSpace);// 7
CGColorSpaceRelease (patternSpace);// 8
pattern = CGPatternCreate (NULL,CGRectMake (0, 0, PATTERN_SIZE, PATTERN_SIZE),
CGAffineTransformIdentity, PATTERN_SIZE, PATTERN_SIZE,
kCGPatternTilingConstantSpacing true, &callbacks);
CGContextSetFillPattern (myContext, pattern, &alpha);// 17
CGPatternRelease (pattern);// 18
//CGContextFillRect(myContext, rect);
CGContextDrawPath(myContext, kCGPathFill);
CGContextRestoreGState (myContext);
}
Here is a snippet of the code where I would like to call the routine:
CGContextSetLineWidth(context, .7);
CGContextSetRGBStrokeColor(context, 0.0, 0.0, 0.0, 1.0);
// Standard non-inverted view scenario.
CGContextBeginPath(context);
CGContextMoveToPoint(context, 0.00 , bMargin);
CGContextAddLineToPoint(context, highPX - curveSP , bMargin);
[self addCurve:context startX:highPX startY:bMargin radius:bo curveSp:curveSP curveDir:FL_BL];
CGContextAddLineToPoint(context, highPX, ((h - tMargin) - curveSP) );
[self addCurve:context startX:highPX startY: (h - tMargin) radius:bo curveSp:curveSP curveDir:FL_TL];
CGContextAddLineToPoint(context, (lowPX - curveSP), (h - tMargin) );
[self addCurve:context startX: lowPX startY: (h - tMargin) radius:bo curveSp:curveSP curveDir:FL_TR];
CGContextAddLineToPoint(context, lowPX, (bMargin + curveSP) );
[self addCurve:context startX:lowPX startY: bMargin radius:bo curveSp:curveSP curveDir:FL_BR];
CGContextAddLineToPoint(context, w, bMargin);
//CGContextDrawPath(context, nonInvertedView);
CGContextDrawPath(context, kCGPathStroke);
// fill with pattern
drawPattern(context);
The actual apple example also includes an NSRect arg in the drawing method, but since I don't want to fill a rect, I figured I could omit that. not sure though.
Thanks
CGContextDrawPath resets the current path. (They used to mention that somewhere, but I couldn't find it in a quick search.)
Save the graphics state before you stroke, then restore before you fill with the pattern.
(I assume you're specifically trying to get an outer stroke by stroking and then filling over half of it. If you want or can accept a centered stroke, kCGPathFillStroke will do the job with a single CGContextDrawPath call.)
So heres an update: I don't fully understand whats happening, but if I drop the code in the drawPattern method into a test app with an empty rect, it draws just like it should. If I drop the code into my method for drawing a path into a view , I get very strange behavior; it even tries to redraw parts of the view controller it should't even know about.
As soon as I deleted the CGContextSaveGState() , CGColorSpaceRelease(), CGPatternRelease(), and the CGContextRestoreGState(), the code started doing exactly what I wanted. I modified the method to this:
static void drawPattern(CGContextRef *pContext){
static CGPatternRef pattern;
static CGColorSpaceRef patternSpace;
static CGFloat alpha = 1.0;
static const CGPatternCallbacks callbacks = {0, &patternSpec, NULL};
patternSpace = CGColorSpaceCreatePattern (NULL);
CGContextSetFillColorSpace (pContext, patternSpace);
pattern = CGPatternCreate (NULL,
CGRectMake (0, 0, PATTERN_SIZE, PATTERN_SIZE),
CGAffineTransformIdentity,
PATTERN_SIZE,
PATTERN_SIZE,
kCGPatternTilingConstantSpacing,
true, &callbacks);
CGContextSetFillPattern (pContext, pattern, &alpha);
}
Now I can either call the defined pattern, or set a define fill color:
CGContextSetFillColor(context);
or:
drawPattern(context);
I would appreciate input on this, because I would like to know if leaving out some of these saveState or Release methods is a problem such as memory leaks.
Thanks
so I would like to know if in cocos2D it is possible to add an animation to the width of a sprite with actions.For example my sprite's width is 100 and its width goes to 200 with animation .(just the width no the height)Thank you :) sorry for my english I'm french :/
yes, you can use action for this.
CCSprite *spr = nil;//your sprite
CGFloat startingWidth = 100;
CGFloat finalWidth = 200;
id action = [CCPropertyAction actionWithDuration:2 key:#"scaleX" from:1 to:finalWidth / startingWidth];
[spr runAction:action];