I am trying to load SVGPath (simple line) in JavaFx 3D viewer. I tried adding the SVGPath class object to Group and added it on scene, but it shows only in 2D. Is there a way I can change this to 3D representation. I also tried using JavaFx 3D Shapes like Box and Cylinder but not sure whether it is a correct way to do that. Following is my code.
Group relationGrp = new Group();
SVGPath path = new SVGPath();
path.setStroke(Color.WHITE);
path.setStrokeWidth(10);
path.setContent("M -15 -60 L -15 15 L 60 15z");
svg3dModelGrp.getChildren().add(path);
I think the SVGPath only allows 2D drawing, why ? Because you just have to introduce (positionX, positionY, and some curve details...) in each action and Logically a line has no depth:
//MoveTo (from positionX and positionY) / LineTo (to positionX and positionY)
Mx y , Lx y ...
You can play with the path to create depth effects by creating many shapes one behind the other with a decremented size but I do not believe that the SVGPath is made for this purpose !
Wikipedia :
Scalable Vector Graphics (SVG) is an XML-based vector image format for two-dimensional graphics
Related
I am using Pandas3D 1.10 (with Python 3.6) and I am trying to generate terrain on the fly.
Currently, I was able to perform this:
Now, my idea is to add textures to this terrain. I plan to add different textures for different kinds of ground and biome, but when I try to add a texture, this is added on the whole terrain.
I only want to add the texture to certain parts of the mesh, so I can combine different textures (dirt, grass, sand, etc) and make a better terrain.
From this Panda3D documentation you can see an example of how to make the terrain:
from panda3d.core import ShaderTerrainMesh, Shader, load_prc_file_data
# Required for matrix calculations
load_prc_file_data("", "gl-coordinate-system default")
# ...
terrain_node = ShaderTerrainMesh()
terrain_node.heightfield_filename = "heightfield.png" # This must be in gray scale, also you can make an image with PNMImage() with code.
terrain_node.target_triangle_width = 10.0
terrain_node.generate()
terrain_np = render.attach_new_node(terrain_node)
terrain_np.set_scale(1024, 1024, 60)
terrain_np.set_shader(Shader.load(Shader.SL_GLSL, "terrain.vert", "terrain.frag"))
In that link, there is also an example of both terrain.vert and terrain.frag.
I tried to apply this guide but it seem that doesn't work on ShaderMeshTerrain, or I think.
ts = TextureStage('ts')
myTexture = loader.loadTexture("textures/Grass.png")
terrain_np.setTexture(ts, myTexture)
terrain_np.setTexScale(ts, 10, 10)
terrain_np.setTexOffset(ts, -25, -25)
The output is the same. It doesn't matter how much I change the numbers of setTextScale and setTexOffset the output is always all with grass.
How can I only implement the texture on a certain part of the model?
Obviously, I can make the image on the fly and do all the modifications with PNMImage(), but it will be slow and difficult, and I am very sure it may be possible to do without re-made the texture each time.
EDIT
I've discovered that I can do this in order to only put a texture in a place:
ts = TextureStage('ts')
myTexture = loader.loadTexture("textures/Grass.png")
myTexture.setWrapU(Texture.WM_border_color)
myTexture.setWrapV(Texture.WM_border_color)
myTexture.setBorderColor(VBase4(0, 0, 0, 0))
terrain_np.setTexture(ts, myTexture)
The problem is that I am not able to change the location of this texture nor its size. Also, note that I don't want to reduce the scale of the texture, when I want to make a texture smaller I mean "cut" or "erase" all the parts that don't fit on the place, not reduce the overall texture size.
Sadly these commands aren't working:
myTexture.setTexScale(ts, LVecBase2(0.5, 250))
myTexture.setTexOffset(ts, LVecBase2(0.15, 0.5))
I'm new to Open Inventor 3D Graphics API and I just want to draw a line between given to 3-D coordinates. Let's say the first point is 0,0,0 and the second is 1,1,1. The documentation and examples of this API are really awful and can't get it out right. I'm using Visual Studio.
If you just need to set the base color (what Open Inventor & OpenGL call diffuse color), which is usually the case for line geometry, then you can set it directly in the SoVertexProperty node.
For example, to make the line in the previous example 'red', add this line:
vprop->orderedRGBA = 0xff0000ff; // By default applies to all vertices
or, more conveniently:
vprop->orderedRGBA = SbColor(1,0,0).getPackedValue();
If you need more control over the appearance of the geometry, add an SoMaterial node to the scene graph before the geometry node.
Assuming you're just asking about creating the line shape - just store the coordinates in an SoVertexProperty node, set that node in an SoLineSet node, then add the line set to your scene graph. Open Inventor will assume that you want to use all the coordinates given, so that's all you need to do.
For just two coordinates it may be easiest to use the set1Value method, but you can also set the coordinates from an array. You didn't say which language you're using, so I'll show the code in C++ (C# and Java would be essentially the same except for language syntax differences):
SoVertexProperty* vprop = new SoVertexProperty();
vprop->vertex.set1Value( 0, 0,0,0 ); // Set first vertex to be 0,0,0
vprop->vertex.set1Value( 1, 1,1,1 ); // Set second vertex to be 1,1,1
SoLineSet* line = new SoLineSet();
line->vertexProperty = vprop;
sceneGraph->addChild( line );
Line thickness is specified by creating an SoDrawStyle property node and adding it to the scene graph before/above the geometry node. Like this:
SoDrawStyle* style = new SoDrawStyle();
style->lineWidth = 3; // "pixels" but see OpenGL docs
parent->addChild( style );
I'm utilizing the Bravura music font.
Here's its font-face definition:
<font-face
font-family="Bravura"
font-weight="400"
font-stretch="normal"
units-per-em="2048"
panose-1="5 6 0 0 0 0 0 0 0 0"
ascent="1638"
descent="-410"
bbox="-889 -4080 4749 4120"
underline-thickness="102"
underline-position="-102"
unicode-range="U+0020-1D1DD"
/>
I'm trying to wrap my head around font metrics. I've studied the explanation on this site: But I'm still unclear.
My goal is to translate the glyphs into a properly scaled SVG path using an SVG symbol viewBox attribute.
So the EM square (which is an imaginary square enclosing each glyph) is 2048x2048 units (defined by units-per-em). A unit is 1/72 of an inch. My monitor DPI is 96x96
Converting this to pixels = 2048 * 96/72 = 2730 1/3 x 2730 1/3
(Let me know if I'm off here)
So each font should natively fit into a 2730 1/3 x 2730 1/3 square?
How does the bounding box #s fit into this process? Are the bbox units in glyph-units as well? (1/72 in)
Should the bbox value below be directly inputted into the viewBox attribute of a symbol?
Do I need to consider ascent and descent values?
Here is a jsfiddle somewhat demonstrating my issue: http://jsfiddle.net/1wqa384u/5/
Any resources or help appreciated.
The em box encompasses the ascent and decent. Notice that ascent-descent=2048.
As for your main question, I think you are confusing yourself a bit. The viewBox tells the browser how to scale the symbol to fit the size specified by the <use> that references it.
So if I understand what you want correctly, your symbol viewBox should just be "0 0 2048 2048".
You should then be able to draw it at, say 12pt, by referencing it like so:
<use xlink:href="#mysymbol" x="100" y="100" width="12pt" height="12pt"/>
You shouldn't have to worry about doing your own DPI conversion.
I am trying to set a single line of static text so it lies across the secreen at 45 degrees.
This is my code but it has no effect.
mLoser = new Text(20, 430, mFont36,"Game Over! No more moves.", getVertexBufferObjectManager());
mLoser.setPosition(400 - mLoser.getWidth()/2, 480 - mLoser.getHeight()-2);
mLoser.setRotationCenter(mLoser.getX(), mLoser.getY());
mLoser.setRotation((float) -0.125);
mLoser.setVisible(false);
mMainScene.attachChild(mLoser);
I have my game working and just trying a few ideas I haven't used before.
Could you explain how this is done.
Solved.
I just had to set the rotation to -45 instead of -0.125. Doh!
A bit more fiddling with the positioning and got what I wanted.
Trying to get these 2 raphael elements to both change color when hovered over one or the other. Here is the code I have. Any help would be appreciated.
var loge_1 = rsr.set();
loge_1a = rsr.rect(235.457, 287.645, 32.523, 45.486),
loge_1b = rsr.rect(235.139, 277.626, 32.933, 6.701);
loge_1.push(loge_1a,loge_1b);
loge_1.attr(logeFill);
I assume you got the code from ReadySetRaphael .... no doubt they have a very good algorithm for Raphael conversion ... try some large SVG files sometime and they will give you a good result .... anyways try this ...
loge_1.mouseover(function(){
loge_1.attr({'fill':'your Desired Color'});
}
loge_1.mouseout(function(){
loge_1.attr({'fill':'original color'});
}
this should change the color of both your rects .... Hope it helps.
Well after searching I didn't find much on the subject. So I have read up on svg elements and changed my "rect" to "path". Here is the W3C svg documentation
And here is the jsfiddle with "path"
To find my rectangles paths I just opened the svg file in Adobe AI. Then made sure my documents units was set to pixels. From there I opened my info window and just copied the my anchor points of my rectangles x & y coordinates into my "path" and presto I have 2 shapes acting as one.