I'm trying to draw a line using ray casting. Basically I want to set up some lines coming from my "player" object out in all directions.
(like so: https://gamedev.stackexchange.com/questions/35013/how-to-handle-3d-collisions-using-raycasting-with-a-reflection-vector)
I want this so I can then use I can see my collision detection visually.
I know I can use different ways to do collision detection, but i'm using this way as a learning detection.
My issue is the code below draws a line but it seems to randomly change length and not always point at the same angle.
var ray = new THREE.Ray( player.model.objects.position, new THREE.Vector3(1, 1, 1));
var geometry = new THREE.Geometry();
// my issue is here. I don't think this is the right way use a ray to workout the second vector?
// EDIT: Realized this should be set at player position and outwards.
//var newx = 300 * ray.direction.x;
//var newz = 300 * ray.direction.z;
// EDIT CODE UPDATE
var newx = (player.model.objects.position.x) + (60 * ray.direction.x);
var newz = (player.model.objects.position.z) + (60 * ray.direction.z);
// THREE.Vector3 {x: 1310.1526178356803, y: 0, z: 1290.8237947033065}
console.log(player.model.objects.position);
geometry.vertices.push( player.model.objects.position);
geometry.vertices.push( new THREE.Vector3(newx, player.model.objects.position.y, newz));
var line = new THREE.Line(geometry, material);
scene.add(line);
Any help appreciated.
I was trying to do the same thing after seeing that model.. Since I tried to do it the same way and couldn't figure it out, I'll offer an alternative.
var line;
function update() {
// Z- DIRECTION
raycaster.ray.direction.set(0, 0, -1);
var geometry = new THREE.Geometry();
intersections = raycaster.intersectObjects( objects );
if ( intersections.length > 0 ) {
var geometry = new THREE.Geometry();
// POSITION OF MESH TO SHOOT RAYS OUT OF
geometry.vertices.push( obj.position );
geometry.vertices.push( intersections[0].point );
scene.remove(line);
line = new THREE.Line(geometry, new THREE.LineBasicMaterial({color: 0x990000}));
scene.add(line);
}
}
So now you have a line shooting out of your mesh into whatever the closest intersect is.
https://dl.dropbox.com/u/42766757/guy.png
Related
I'm trying to update make my camera far clip plane to sit on Vector3(0,0,0) no matter how close or far the camera gets, I've managed to find a way of updating the far clip plane dynamically but I can't get this plane to face my camera.
Thanks, C.
var matrix = new THREE.Matrix4();
matrix.extractRotation(camera.matrix);
var direction = new THREE.Vector3();
direction.subVectors( new THREE.Vector3(0,0,0), camera.position );
direction.normalize();
var N = new THREE.Vector3(0, 1, 0);
N.applyMatrix4(matrix);
var planePos = new THREE.Vector3(0,0,0);
var clipPlane = new THREE.Plane();
clipPlane.setFromNormalAndCoplanarPoint(N, planePos);
clipPlane.applyMatrix4(camera.matrixWorldInverse);
clipPlane = new THREE.Vector4(clipPlane.normal.x, clipPlane.normal.y, clipPlane.normal.z, clipPlane.constant);
var q = new THREE.Vector4();
var projectionMatrix = camera.projectionMatrix;
q.x = (sgn(clipPlane.x) + projectionMatrix.elements[8]) / projectionMatrix.elements[0];
q.y = (sgn(clipPlane.y) + projectionMatrix.elements[9]) / projectionMatrix.elements[5];
q.z = -1.0;
q.w = (1.0 + projectionMatrix.elements[10]) / camera.projectionMatrix.elements[14];
// Calculate the scaled plane vector
var c = new THREE.Vector4();
c = clipPlane.multiplyScalar(2000.0 ); //clipPlane.multiplyScalar(2.0 / clipPlane.dot(q)); /// clipPlane.dot(q)
// Replace the third row of the projection matrix
projectionMatrix.elements[2] = c.x;
projectionMatrix.elements[6] = c.y;
projectionMatrix.elements[10] = c.z + 1.0;
projectionMatrix.elements[14] = c.w;
If you want to reset the far plane parameter for a camera, you can use this pattern
camera.far = new_value;
camera.updateProjectionMatrix();
In your particular case, you can do this:
camera.far = camera.position.length();
camera.updateProjectionMatrix();
three.js r.72
I'm learning Raphael and I wonder how to call the same function from both events, mousedown and mouse up, in order to draw two dots with every click.
You can test the code here: jsfiddle
var w = window.innerWidth;
var h = window.innerHeight;
var paper = Raphael(0, 0, w, h);
var canvas = paper.rect(0, 0, w, h,12);
canvas.attr('fill', 'lightgrey');
canvas.mouseup(function (event, a, b) {
// get bounding rect of the paper
var bnds = event.target.getBoundingClientRect();
var targetBox = this.getBBox();
// adjust mouse x/y
var mx = event.clientX - bnds.left;
var my = event.clientY - bnds.top;
// divide x/y by the bounding w/h to get location %s and apply factor by actual paper w/h
var fx = mx/bnds.width * canvas.attrs.width + targetBox.x;
var fy = my/bnds.height * canvas.attrs.height + targetBox.y;
// cleanup output
fx = Number(fx).toPrecision(3);
fy = Number(fy).toPrecision(3);
paper.circle(fx, fy, 1).attr("fill","black", "stroke-width",0);
});
I'm pretty new to RaphaelJS, and I did never need to call a function from two mouse events with javascript. So, I'm confused. Any help will be appreciated.
You can just create a new function, which takes in the event parameter, like this...
canvas.mouseup( eventDraw );
canvas.mousedown( eventDraw );
function eventDraw( event ) {
//... do stuff
};
jsfiddle
I have a special case when I want to do something like
let predicate = NSPredicate(format:"
DISTANCE(\(UserLocation),photoLocation) <= visibleRadius AND
DISTANCE(\(UserLocation),photoLocation" <= 10)"
var query = PFQuery(className:"Photo", predicate:predicate)
Basically, I want to get all photos that are taken within 10km around my current location if my current location is also within the photo's visible radius
Also, photoLocation and visibleRadius are two columns in the database, I will supply UserLocation as a PFGeoPoint.
Is it possible to achieve this? In my opinion, I don't think that I may call, for example, photoLocation.latitude to get a specific coordinate value. May I?
I'll appreciate you a lot if this can be achieved!!
I found this at the pares.com docs here is the link
let swOfSF = PFGeoPoint(latitude:37.708813, longitude:-122.526398)
let neOfSF = PFGeoPoint(latitude:37.822802, longitude:-122.373962)
var query = PFQuery(className:"PizzaPlaceObject")
query.whereKey("location", withinGeoBoxFromSouthwest:swOfSF, toNortheast:neOfSF)
var pizzaPlacesInSF = query.findObjects()
This code fetch you all the objects that are in a rectangle area defined by the swOfSF & neOfSF objectc, where seOfSF is in the south-west corner and neOfSF is in the north-east corner.
You can make some alterations to the code and get all the objects in rectangle area that your object is in middle
i would recommend that you don't use a radius, because it will take a lot of calculations. Instead use a rectangle area (like in the code i gave you).
just calculate what is the max/min longitude & max/min latitude from your position and fetch all the objects that are in between. you can read about how to fine the min/max longitude & latitude here Link
I managed to solve it using Parse Cloud Code, here is the quick tutorial
Parse.Cloud.define("latestPosts", function(request, response) {
var limit = 20;
var query = new Parse.Query("Post");
var userLocation = request.params.userLocation;
var searchScope = request.params.searchScope;
var afterDate = request.params.afterDate;
var senderUserName = request.params.senderUserName;
query.withinKilometers("Location", userLocation, searchScope);
query.greaterThan("createdAt", afterDate);
query.notEqualTo("senderUserName",senderUserName);
query.ascending("createdAt");
query.find({
success: function(results) {
var finalResults = results.filter(function(el) {
var visibleRadius = el.get("VisibleRadius");
var postLocation = el.get("Location");
return postLocation.kilometersTo(userLocation) <= visibleRadius;
});
if (finalResults.length > limit) {
var slicedFinalResults = results.slice(0, 20);
response.success(slicedFinalResults);
} else {
response.success(finalResults);
}
},
error: function() {
response.error("no new post");
}
});
});
The code above illustrate a basic example of how to use Cloud Code. Except, I have to make sure that all the returned image are in the union of user's search scope and photo's visible circle. There are more techniques such as Promises. But for my purpose, the code above should just suffice.
I am a Photoshop beginner and currently use version Photoshop CS3. I use keyboard shortcut all the time to speed up the design process such as creation of new layers etc.
However, one command I feel Photoshop must have is to create a new layer below the current working layer and therefore I cannot assign it via a shortcut.
I have to create a new layer above the current layer and then manually drag it below the current layer which I feel can be automated using action or scripting, both of which are difficult for me being a beginner.
Can anybody help me in this regard.
Thanks
dkj
It can be scripted with the following:
I've simplified my answer - you don't need to find the index, you can use the active layer instead.
create_new_layer("Gwen!");
// function CREATE NEW LAYER (layername)
// --------------------------------------------------------
function create_new_layer(layername)
{
if (layername == undefined) layername = "Layer";
// create new layer at top of layers
var originalLayer = app.activeDocument.activeLayer;
var layerRef = app.activeDocument.artLayers.add();
// name it & set blend mode to normal
layerRef.name = layername;
layerRef.blendMode = BlendMode.NORMAL;
// Move the layer below
layerRef.moveAfter(originalLayer);
// Move the layer above if you desire
// layerRef.moveBefore(originalLayer);
}
You can then record this script as an action and put on a keyboard short cut.
Few years ago i thought that native PS API working with DOM is cool and should work faster, but actually under the hood it's callstack often even bigger than same commands performed via actions. + Also sometimes DOM functions consist of multiple underlying calls, like artLayers.add() for example which is actually make layer + move it to top of the document. So here's action version of that functionality from my PS scripting library:
// get current layer number
function curLyrN(){
if(app.activeDocument.artLayers.length<2) return 1;
var idLyr = charIDToTypeID("Lyr ");
var idItmI = charIDToTypeID("ItmI");
var aref = new ActionReference();
aref.putEnumerated(idLyr, charIDToTypeID("Ordn"), charIDToTypeID("Trgt"));
var id = executeActionGet(aref).getInteger(charIDToTypeID("LyrI"));
aref = new ActionReference();
aref.putProperty(charIDToTypeID("Prpr"), idItmI);
aref.putIdentifier(idLyr, id);
id = executeActionGet(aref).getInteger(idItmI);
if(id) return id;
return 0;
}
// select [LayerNum], optionally [add] to selection (if add=2: with inclusion)
function selLyr(LyrN,add){
var adesc = new ActionDescriptor();
var aref = new ActionReference();
aref.putIndex(charIDToTypeID("Lyr "), LyrN);
adesc.putReference(charIDToTypeID("null"), aref);
if(add){
add = (add==2) ? stringIDToTypeID("addToSelectionContinuous") : stringIDToTypeID("addToSelection");
adesc.putEnumerated(stringIDToTypeID("selectionModifier"),stringIDToTypeID("selectionModifierType"),add);
}
adesc.putBoolean(charIDToTypeID("MkVs"), false);
return executeAction(charIDToTypeID("slct"), adesc, DialogModes.NO);
}
// move current layer to [LayerNum]
function movLyr(LyrN){
var idLyr = charIDToTypeID("Lyr ");
var adesc = new ActionDescriptor();
var aref = new ActionReference();
aref.putEnumerated(idLyr, charIDToTypeID("Ordn"), charIDToTypeID("Trgt"));
adesc.putReference(charIDToTypeID("null"), aref);
aref = new ActionReference();
aref.putIndex(idLyr, LyrN);
adesc.putReference(charIDToTypeID("T "), aref);
adesc.putBoolean(charIDToTypeID("Adjs"), false);
return executeAction(charIDToTypeID("move"), adesc, DialogModes.NO);
}
// create new empty layer
function mkLyr(){
var aref = new ActionReference();
aref.putClass(charIDToTypeID("Lyr "));
var adesc = new ActionDescriptor();
adesc.putReference(charIDToTypeID("null"), aref);
return executeAction(charIDToTypeID("Mk "), adesc, DialogModes.NO);
}
// count all inner layers from layer-set (group)
function cntLyrS(lyrs,c){
if(!c){
if(lyrs.typename!='LayerSet') return 0;
c = 0;
}
var ls = lyrs.layers.length;
var i = 0;
while(i<ls){
c++;
if(lyrs.layers[i].typename=='LayerSet') c=cntLyrS(lyrs.layers[i],c);
i++;
}
return c+1;
}
// make new layer below current or [LayerNum], optionally [ignoreGroups]
function mkLyrBelow(LyrN,noGr){
var doc = app.activeDocument;
if(!doc) return false;
if(LyrN){
selLyr(LyrN);
}else{
LyrN = curLyrN();
if(!LyrN) return false;
}
var actv = doc.activeLayer;
if(actv.isBackgroundLayer) actv.isBackgroundLayer=false;
mkLyr();
if(curLyrN()==LyrN) return true;
if(!noGr){
var lc = cntLyrS(actv);
if(lc && lc<LyrN-1) LyrN -= lc;
}
return movLyr(LyrN-1);
}
And even tho it looks pretty cumbersome and scary - i doubt that it will perform much slower. And as a bonus it will create minimal amount of actions in the history (no unnecessary layer moves) + it will correctly work with background layer + it will work properly with the groups (layer-sets): if group is opened - it will create new layer inside of it, and if group is closed it will correctly move layer under the whole group-structure including other possible groups inside the selected one.
Use it like that: mkLyrBelow(); to create new layer under selected one, or mkLyrBelow(LayerNumber); to create layer under another one via it's number, also u can optionally add 2d parameter to ignore groups (it will move new layer inside the group even if it's closed): mkLyrBelow(LayerNumber,true); or mkLyrBelow(0,1);...
P.S. don't get me wrong about ActionRefs - they're not the silver bullet, just oftenly have some more convenience in the end, but ofc best results obtained when u combine ARef's with native API. Just believe me on that, i've coded my first PS script like 8 years ago, so i've tried pretty much everything =)
If I understand your question correctly, Photoshop already has these shortcuts
Ctrl+Shift+N (Creating New Layer)
Ctrl+] (To move the layer up)
Ctrl+[ (To move the layer down)
I am doing a very simple stuff, my goal is to move one skeleton based on the position of the other skeleton, for this i am based myself on a HipCenter position.
(This algoritm could be wrong, this question is about a exception ocurring in the foreach loop)
Here is my actual code:
public static Skeleton MoveTo(this Skeleton skOrigin, Skeleton skDestiny)
{
Skeleton skReturn = skOrigin; // just making a copy
// find the factor to move, based on the HipCenter.
float whatToMultiplyX = skOrigin.Joints[JointType.HipCenter].Position.X / skDestiny.Joints[JointType.HipCenter].Position.X;
float whatToMultiplyY = skOrigin.Joints[JointType.HipCenter].Position.Y / skDestiny.Joints[JointType.HipCenter].Position.Y;
float whatToMultiplyZ = skOrigin.Joints[JointType.HipCenter].Position.Z / skDestiny.Joints[JointType.HipCenter].Position.Z;
SkeletonPoint movedPosition = new SkeletonPoint();
Joint movedJoint = new Joint();
foreach (JointType item in Enum.GetValues(typeof(JointType)))
{
// Updating the position
movedPosition.X = skOrigin.Joints[item].Position.X * whatToMultiplyX;
movedPosition.Y = skOrigin.Joints[item].Position.Y * whatToMultiplyY;
movedPosition.Z = skOrigin.Joints[item].Position.Z * whatToMultiplyZ;
// Setting the updated position to the skeleton that will be returned.
movedJoint.Position = movedPosition;
skReturn.Joints[item] = movedJoint;
}
return skReturn;
}
Using F10 to debug everything works fine ultin the second pass in te foreach loop.
When i am passing for the second time in the foreach i get a exception on this line
skReturn.Joints[item] = movedJoint;
The exception says:
JointType index value must match Joint.JointType
But the value is actualy the Spine.
Whats wrong?
Solved, here is the solution
Joint newJoint = new Joint(); // declare a new Joint
// Iterate in the 20 Joints
foreach (JointType item in Enum.GetValues(typeof(JointType)))
{
newJoint = skToBeMoved.Joints[item];
// applying the new values to the joint
SkeletonPoint pos = new SkeletonPoint()
{
X = (float)(newJoint.Position.X + (someNumber)),
Y = (float)(newJoint.Position.Y + (someNumber)),
Z = (float)(newJoint.Position.Z + (someNumber))
};
newJoint.Position = pos;
skToBeChanged.Joints[item] = newJoint;
}
This will work.