Edit This was a bug that has been fixed in https://github.com/threerings/playn/commit/137ce50dddd2716f84c38ec1568d7ae5a368434b. See Par Eklund's answer for details.
Before I begin: I am a novice at game programming in general so it's very likely that I have a fundamental misunderstanding of the tools I am using. However I'll push on with my question...
Whenever I try to draw something on my Surface Layer during the paint method I get a black screen. If I draw during the init method it shows up OK.
I am trying to replicate the code under the Surface Layer banner here. The code in question is this:
public void paint() {
// Draw 100 random peas imperatively.
surf.clear(0);
for (int i = 0; i < 100; ++i) {
int x = (int)(random() * WIDTH);
int y = (int)(random() * HEIGHT);
surf.drawImage(pea, x, y);
}
}
I am using PlayN 1.4 so while that code doesn't directly match up to what I am writing I thought I at least had the equivalent (except I am drawing white rectangles):
public void paint(final float alpha) {
surfaceLayer.surface().clear();
surfaceLayer.surface().setFillColor(Color.rgb(255, 255, 255));
for (int i = 0; i < 100; ++i) {
int x = (int) (Math.random() * width);
int y = (int) (Math.random() * height);
surfaceLayer.surface().fillRect(x, y, 5, 5);
}
}
Nothing is rendered to the screen. If I move that code into the init method it renders as expected.
Now interestingly if I make PlayN 1.3.1 project and use the exact same code it renders fine during the paint method (given that I'm still using the exact same code I'm not sure what version the PlayN website is using in its example code...).
What have I missed here? Has 1.4 changed something to do with the Surface Layer and I must use it differently now? Thanks.
I am basically a novice to game programming myself and I have run in to the same problem as you (same symptoms at least) with PlayN 1.5-SNAPSHOT. I filed an issue for it here: http://code.google.com/p/playn/issues/detail?id=205
Also, my experience is that it does not seem to be specifically related to whether rendering is done in the init- or the paint method. Rather, it seems as if rendering only succeeds the _first_time_ (first frame rendering occurs). Please see the attached file in the issue for a (somewhat) minimal example.
Like I stated in the issue, I suspect that this is related to the GL20 implementation and how frame buffers are being managed, but given that I am even more a novice on OpenGL you should take my speculation with a huge grain of salt.
The PlayN main contributors should be able to answer and solve this pretty quickly though. Let's hope that we receive their attention soon. :)
Related
For neuroscience research I'm attempting to train rats to press shapes on a touch screen. Ideally, these shapes would be highly distinct polygons or blobs to make it easier for the rats to discriminate. However, to limit some biases toward certain shapes, I'd like to keep the area of each shape equivalent. I've been trying to achieve this on p5.js, but I'm very new to this.
The code I've got so far provides some of the shape randomness, but not the consitency in area:
function setup() {
createCanvas(500, 500);
background(255);
fill(0);
translate(width/2, height/2);
beginShape();
for(let i = 0; i < 5; i++) {
const x = random(-250, 250);
const y = random(-250, 250);
vertex(x, y);
endShape();
}
}
Any help achieving this would be very appreciated
Maybe it's not what you need, the shapes are all inscribed in a circle(edit:the second code ones), not a bounding box as I said earlier.
Both examples are online at p5js editor:
The code I had was more free form, it will eternally increase the number of sides:
about 20 sides:
about 130 sides
But at the begining its more what I think you need
the code is here:
https://editor.p5js.org/v-k-/sketches/siYtDw423
And...
I made a tweeked version to try to go closer to what I think you want :)
The code is here:
https://editor.p5js.org/v-k-/sketches/oMsWC2NHv
Perhaps you can play with the numbers to get What you need. For instance:
You can set the number of sides, or even reject sides smaller than something.
It's very simple stuff ;) Easy to tweek.
Have fun, hope the rats like it.
I've been building something in aframe (using the current master build from github as of 23rd March 2018) and have noticed that there are two sets of rotations that are identical that I don't think should be.
A model looks the same with its rotation attribute "270 90 90" and "270 180 0".
Similarly - setting the rotation attribute to "270 270 90" and "270 0 0" look the same.
I created a little demo to show this here - http://marcamillian.com/VR/rotationIssue.html.
Is this a bug or am I mis-understanding something?
=== Further information ===
I came across this when trying to add rotating animations a model from "270 90 0" along its roll axis and yaw axis and not getting the same motion on each.
After checking all of my functions I started setting the attribute on the model directly and getting the model looking the same for different rotation positions.
This is a pretty common problem in 3D computer graphics. Welcome to the gimbal lock problem! It is basically an issue you run into when trying to set rotations using "Euler" angles, especially when rotating in multiples of 90 degrees. If you are going to rotate like this try to only rotate by two axes (e.g. x and y) instead of all 3 (x,y,z).
More information here on gimbal lock: https://www.youtube.com/watch?v=zc8b2Jo7mno&feature=youtu.be
An even better practise is to rotate using quaternions instead. I will also note that it is best practise to use components to make sure A-Frame is available to modify, or not as recommended a "loaded" event listener on a-scene (see this SO question for more info. How to detect when a scene is loaded in A-Frame?):
//listen for scene load s0 we know Aframe and Threejs are around to access. A snipped of your code, modified slightly for some direction ...
document.querySelector('a-scene').addEventListener('loaded', function () {
//AFRAME loaded
const scene = document.querySelector('a-scene');
const arrowElem = scene.querySelector(".shape-container");
//now set your click listener
setButton.addEventListener('click',function(){
let rotationValue = `${inputPitch.valueAsNumber} ${inputYaw.valueAsNumber} ${inputRoll.valueAsNumber}`
//arrowElem.setAttribute('rotation', rotationValue); //your way
//this doesn't work well ...
//arrowElem.object3D.rotation.set( THREE.Math.degToRad(inputPitch.valueAsNumber),
THREE.Math.degToRad(inputYaw.valueAsNumber),
THREE.Math.degToRad(inputRoll.valueAsNumber)
);
//consider how you can use quaternions instead
let quaternion = new THREE.Quaternion();
quaternion.setFromAxisAngle( new THREE.Vector3( 0, 1, 0 ), Math.PI / 2 ); //might have to change your logic to better use this functionality ...
})
});
I have to plot a graph in processing by the feedback from encoder motors of the bot. so I have two variables basically left motor encoder and right motor encoder. I planned to vary on in x-axis and another in y-axis. While I went through some of the code on internet I found that, almost everyone has written the graph part code in serial event itself?
So my first doubt is why do they write it in serial event() function rather than void draw()? Another thing is when I tried to write my code for graph in void draw() it had a pseudo code something like this:
xpos1=0,ypos1=height;
void draw():
line(xpos1,ypos1,xpos,height-ypos);// obviously the data(xpos,ypos) is mapped with the width and height of the processing ide window.
xpos1=xpos;
ypos1=height-ypos;
if(xpos1>=width)
{
xpos1=0;
}
if(ypos1>=height)
{
ypos1=0;
}
So I get to see only a small dot traversing on processing ide window and I cannot see the older path that my line has travelled which in the case of the sites which I described when wrote the similar piece of code in serial event() they had a whole graph getting made on the processing window.
Where am I getting wrong? Also is there any alternative to plot the graph using void draw()? I want to vary both xpos as well as ypos as i get two feedbacks form left motor and right motor.
Screenshot of my attempted graph in different frames!
Image
Screenshot of one of the graphs made by somewhat the similar code displayed above but written in the serial event() available on the internet:
As stated in the comments, there are too many subquestions here.
Regarding the question relative to the code, there is one main line that is making the code much more complex than it has to be. You are trying to draw a line between each and every couple of numbers received by the two encoders. There is no need to do that. When plotting a graph, I personally use the point(x,y) function. It's much easier to implement for prototyping purposes, and adjusting the frameRate() at which the sketch is running, you won't notice the difference.
void draw() {
point(encoder1, encoder2);
if (encoder1 >= width) {
encoder1 = encoder1 - width;
}
if (encoder2 >= height) {
encoder2 = encoder2 - height;
}
}
A simple sketch like this one will do the job.
The other thing that is not quite clear is the initialisation of the variables. Usually you initialise a variable if it's continuously increasing, like time, but from your description you want to plot on the X axis one encoder, and on the Y axis the other encoder. So wouldn't it be better to map the values to start with in order not to have them go out of the canvas range?
Please edit the question so that the code is clear and concise, following these guidelines, and try to ask one question per post.
So basically when I try to draw more a mesh inside an FBX file its orientation is always removed and it's scaled down. I'm not sure if the issue is caused by code or the way I'm exporting the FBX files. I have been trying to narrow down the cause and I am fairly sure it's not caused by the way I export the FBX (but I could be wrong), so it's either the XNA content pipeline or my drawing code
Here are some pics I took to show my problem, where the gray background is in 3Ds Max as I see it and red background is in XNA:
THis is as it appears in 3D StudioMax: http://i.stack.imgur.com/e0oW4.png
This is how it appears in XNA: http://i.stack.imgur.com/1vOcx.png
Both are being viewed from the same angle and direction but varying distances.
Now what is really odd is if I create another mesh in max, say a box, and export that (along with the original model), it works fine: http://i.stack.imgur.com/SIDg9.png
So long as there is more than one mesh in the fbx model it draws properly (though I'm still suspicious if it's drawing with proper scaling applied, i.e. if in Max it is 1 unit long in XNA it becomes something like 1.27 units long), if there is less its orientation which I applied to it in 3D studio max is removed when I draw it.
This is how I draw the model:
model.CopyAbsoluteBoneTransformsTo(boneTransforms);
foreach (ModelMesh mesh in model.Meshes)
{
foreach (BasicEffect effect in mesh.Effects)
{
effect.World = boneTransforms[mesh.ParentBone.Index];
Vector3 cameraPosition = Camera.Get.Position;// new Vector3(0, 0, 0);
//cameraPosition.X = -Camera.Get.PosX;
//cameraPosition.Y = Camera.Get.PosY;
effect.View = Camera.Get.View;// Matrix.CreateLookAt(cameraPosition, cameraPosition + Camera.Get.LookDir, Camera.Get.Up);
effect.Projection = Matrix.CreatePerspectiveFieldOfView(MathHelper.PiOver4,
BaseGame.Get.GraphicsDevice.Viewport.AspectRatio,
0.01f, 1000000); //Matrix.CreateOrthographic(800 / 1, 480 / 1, 0, 1000000);
//effect.TextureEnabled = true;
effect.LightingEnabled = true;
effect.PreferPerPixelLighting = true;
//effect.SpecularColor = new Vector3(1, 0, 0);
}
mesh.Draw();
}
Obviously mesh.draw() is called twice when there is more than one mesh in the fbx file..
Generally if you are having a problem with the position or scale of the mesh while rendering, then it's likely to be related to the matrices. Not necessarily the exporting, but rather how you use them in the code.
I use blender3d for modelling, but I know that Blender3d actually defines different spaces when you are creating the meshes within the editor. For example, if you create a mesh while in 'object' mode, the position/rotation/scale of the object in the scene will not be exported (because that object will be the root of a new tree, centered around 0,0,0). So I would check for a similar situation in 3DMax - make sure you are transforming the vertices in Max relative to 0,0,0, or else you may lose the 'initial' translation and when you render in XNA, all the objects will be rendered around your 0,0,0 (i.e. appear mixed together).
Failing that, and I can't remember exactly off the top of my head, but I think you may need to multiply the current mesh's absolute matrix transform with that of the parent's world matrix transform. Although it's been a while so I'm not too sure.
I have a 2D surface ( Grid ) with 50 elements at different locations.
I need to decide which are the 10 closest elements to a given point.
In addition, the given point is constantly moving and i need to do the calculation on each movement.
I know I can calculate the Euclidean distance to each point on each movement, but I want a faster way.
Thanks.
It sounds like you're trying to come up with a way where you can take the 10 closest points at time t and use those to help you figure out the 10 closest at time t+1. Here's an idea to consider.
When you calculate the 10 closest points, also store the angular direction of where they are relative to your current location. Then, when you move you can calculate the direction in which you moved. Focus your search on the space that's opened up to you (think of a circle around point A and another around point B. The space in B but not in A is where you want to focus your search).
Of course, to do this you need to have some way of searching in a particular area of the grid instead of doing a linear search through an array of points to find those close to you. I'd recommend looking into BSP trees for that. If you're not doing it already, using BSP trees instead of linear search might alone be the performance boost you're looking for.
So, I am going to put all the attempts that I went over to figure out my implementation and hopefully you will be able to figure out the best approach for you project.
I am working on somewhat similar project to what you have mentioned. But in my case I need to do extra cycles once I found the points within a given distance threshold. I have tried few iterations, first I started by creating a distance grid. Keep in mind, I am not working on 2D surface but I don't think changing this to 2D will take much work.
Here is how I developed my distance grid (its so simple even a cave man can do it, I making fun of myself) , Also keep in mind I didn't continue using the grid to finish up my implementation.
public double[][] distanceGrid() {
double[] gridSize = combineArrays(generateClusters(1, 3), generateClusters(12, 15));
double [][] pointsDistanceGrid = new double[gridSize.length][gridSize.length];
for (int i = 0; i < pointsDistanceGrid.length; i++) {
for (int j = 0; j < pointsDistanceGrid[i].length; j++) {
pointsDistanceGrid[i][j] = Math.abs(gridSize[i] - gridSize[j] );
System.out.print(" " + pointsDistanceGrid[i][j]);
}
System.out.println("");
}
return pointsDistanceGrid;
}
As I mentioned I didn't use it.
Since I had to deal with a distance threshold, and I decided before finding "The Nearest" i wanted to see all the points that are closer to the particular point that I am looking at, so I implemented this method.
/**
* Given a point method returns an array with point that are within the limit of threshold.
* #param point
* #return
*/
public double[] pointsWithinThreshold(double point) {
double[] neighbors = new double[bigCluster.length];
for (int i = 0; i < bigCluster.length; i++) {
if (bigCluster[i] != point) {
double distance = 0;
distance = Math.abs(point - bigCluster[i]);
if (distance <= getDistanceThreshold()) {
neighbors[i] = bigCluster[i];
}
}
}
return neighbors;
}
After this I realize I don't really care what are all the closest points so I end up not using this and refractor some of this functionalities to a method where I get the closest member and do recursive DFS.
Let me know if you would like to see that, I didn't put it here coz I thought you only need to know the closest 10 member.
Hope this helps and good luck.