Jump to content

How might I draw on a plane instead of a ground object


Recommended Posts

Hello,

 

I'm wrapping up a realtime multi-user drawing app using elements from an example joshcamas posted recently.  I'm not including the GUI and much of the server calls in my example below, so running this script wil provide errors, but the whole script is 3x as large.  However, if someone might help me to accomplish 2 things, I would be grateful.  

 

1. Draw on a plane using a dynamic texture.

2. The base color of the plane is a color3 white (or other.)

 

Here's the example:

 

 
var createScene = function () {
 
    var scene = new BABYLON.Scene(engine);
 
    var camera = new BABYLON.FreeCamera("camera1", new BABYLON.Vector3(0, 5, -10), scene);
    camera.setTarget(BABYLON.Vector3.Zero());
 
 
    var light = new BABYLON.HemisphericLight("light1", new BABYLON.Vector3(0, 1, 0), scene);
        light.intensity = 0.7;
 
        var groundSize = 20;
        var textureResolution = 1024;        
    var ground = BABYLON.Mesh.CreateGround("ground1", groundSize, groundSize, 2, scene);
        
        //Create dynamic texture
        var texture = new BABYLON.DynamicTexture("dynamic texture", textureResolution, scene, true);        
        var textureContext = texture.getContext();
        
        var materialGround = new BABYLON.StandardMaterial("Mat", scene);                                
        materialGround.diffuseTexture = texture;
        //materialGround.alpha = 0.2;        
        //materialGround.diffuseColor = new BABYLON.Color3(1.0, 1.0, 1.0);
        ground.material = materialGround;
        
        var textureSize = texture.getSize();
        texture.update();
        
        //Here
        var maskcanvas = document.createElement('canvas');
        maskcanvas.width = textureSize.width;
        maskcanvas.height = textureSize.height;
        var maskcontext = maskcanvas.getContext('2d');
 
        //And
        var brushcanvas = document.createElement('canvas');
        brushcanvas.width = textureSize.width;
        brushcanvas.height = textureSize.height;
        var brushcontext = brushcanvas.getContext('2d');
        
        // we will call
        var textureComplete = false;        
        var texture_complete = function() 
        {
                 textureComplete = true;
        };
        
        //Prepare
        var mask = new Image();
        //mask.crossOrigin = "Anonymous"; // if mask.src = http://
        mask.src = 'mask_1.png';
        mask.onload = texture_complete;
        
        // Prepare
        var img = new Image();
        //img.crossOrigin = "Anonymous";
        img.src = 'grass.jpg';
        img.onload = texture_complete;        
        
        var isDown = false;
        //Updater
 
        var draw = function(pickResult)
        {
                var x = pickResult.x,
                    z = pickResult.z,
                    brushSize = 5;
                                
                //Check
                if(textureComplete == false) {
                        return;
                }                
                
                //
                x = (x + (groundSize/2));
                x = (x - (ground.position.x));
                z = (z - (ground.position.z));
                z = ((groundSize/2) - z);
 
                //
                x = (x/groundSize)*textureSize.width;
                z = (z/groundSize)*textureSize.height;
                
                //Ok!
                brushcontext.save();
                brushcontext.clearRect(0, 0, textureResolution, textureResolution);
                //maskcontext.globalAlpha = 0.4;
                brushcontext.drawImage(img, 0, 0, textureResolution, textureResolution, x-(brushSize), z-(brushSize), brushSize*2, brushSize*2);                
 
 
                
                brushcontext.restore();
                
                //Now
                maskcontext.save();
                maskcontext.clearRect(0, 0, textureSize.width, textureSize.height);
                //maskcont
                maskcontext.drawImage(mask, 0, 0, mask.width, mask.height, x-(brushSize), z-(brushSize), brushSize*2, brushSize*2);
                maskcontext.globalCompositeOperation = 'source-in';                
                
                //Now
                maskcontext.drawImage(brushcanvas, 0, 0);
 
                maskcontext.restore();
                
                textureContext.save();
                
                //And
                textureContext.drawImage(maskcanvas, 0, 0);
 
                textureContext.restore();
                texture.update();
        };
 
 
 
 
         var draw2 = function(xval,yval,zval)
        {
                var x = xval,
                    z = zval,
                    brushSize = 5;
 
                //Check
                if(textureComplete == false) {
                        return;
                }
 
                //
                x = (x + (groundSize/2));
                x = (x - (ground.position.x));
                z = (z - (ground.position.z));
                z = ((groundSize/2) - z);
 
                //
                x = (x/groundSize)*textureSize.width;
                z = (z/groundSize)*textureSize.height;
 
                //Ok!
                brushcontext.save();
                brushcontext.clearRect(0, 0, textureResolution, textureResolution);
                //maskcontext.globalAlpha = 0.4;
                brushcontext.drawImage(img, 0, 0, textureResolution, textureResolution, x-(brushSize), z-(brushSize), brushSize*2, brushSize*2);
 
 
 
                brushcontext.restore();
 
                //Now
                maskcontext.save();
                maskcontext.clearRect(0, 0, textureSize.width, textureSize.height);
                //maskcont
                maskcontext.drawImage(mask, 0, 0, mask.width, mask.height, x-(brushSize), z-(brushSize), brushSize*2, brushSize*2);
                maskcontext.globalCompositeOperation = 'source-in';
 
                //Now
                maskcontext.drawImage(brushcanvas, 0, 0);
 
                maskcontext.restore();
 
                textureContext.save();
 
                //And
                textureContext.drawImage(maskcanvas, 0, 0);
 
                textureContext.restore();
                texture.update();
        };
        
        
        var onPointerDown = function() { 
                isDown = true;
                var pickinfo = scene.pick(scene.pointerX, scene.pointerY);
            if (pickinfo.hit) {
                draw(pickinfo.pickedPoint);
                // Send Poninter Down Info to Server
                if (connected){
                 WInfo.move=0;
                 WInfo.x= pickinfo.pickedPoint.x;
                 WInfo.y= pickinfo.pickedPoint.y;
                 WInfo.z= pickinfo.pickedPoint.z;
                socket.emit('writing',WInfo);
                }
            }
        }
        var onPointerUp = function() { isDown = false; }
        var onPointerMove = function() {
                if(isDown) {
                        var pickinfo = scene.pick(scene.pointerX, scene.pointerY);
                if (pickinfo.hit) {
                    draw(pickinfo.pickedPoint);
                 // Send Pointer Move Info to Server
                 if (connected){
                 WInfo.move=1;
                 WInfo.x= pickinfo.pickedPoint.x;
                 WInfo.y= pickinfo.pickedPoint.y;
                 WInfo.z= pickinfo.pickedPoint.z;
                 socket.emit('writing',WInfo);
                }
 
                }
                }        
        }
        
 
 
    canvas.addEventListener("pointerdown", onPointerDown, false);
    canvas.addEventListener("pointerup", onPointerUp, false);
    canvas.addEventListener("pointermove", onPointerMove, false);
        
        scene.onDispose = function () {
        canvas.removeEventListener("pointerdown", onPointerDown);
        canvas.removeEventListener("pointerup", onPointerUp);
        canvas.removeEventListener("pointermove", onPointerMove);
    }
 
 
 
 
 // LG   return scene;
 
// LG };
      // -------------------------------------------------------------
 
      // Now, call
// LG      var scene = createScene();
 
      // Register a
      engine.runRenderLoop(function () {
         scene.render();
      });

 

 

Thanks,

 

DB

Link to post
Share on other sites

So I need to apply the dynamic texture to a plane which I can rotate and translate - but send the texture through the canvas to the plane.  I have a mask canvas in the script above, which I will remove as it's not necessary.  Any thoughts to how I can use a plane to pass color to a dynamic texture applied to the plane?  I've tried within my script, but have failed - perhaps due to the methods I'm employing.  Any help would be greatly appriciated as I'm almost a week behind and should finish the app today.

Link to post
Share on other sites

Hi DB and others!

 

 

send the texture through the canvas to the plane

 

I'm not sure what you are saying, with this.  You don't need to 'send' anything, because dynamicTextures are derived from 2D Canvas... but it's all done behind the scene... with the BJS dynamicTexture code.  You can simply call drawText... like the docs show.  If you want a transparent background (so the color of the plane is used for the DT background color)... then you set the dynamicTexture.hasAlpha = true... and then use the word "transparent" (with quotes), like this...

 

dynamicTexture.drawText("test", 0, 0, ?, ?, "transparent")

 

There's a few demos around that have DT "transparent" background set.  Search the forum with some tasty fodder.

 

And, of course, if you want the TEXT to take-on the color of the plane, just peek the plane.diffuseColor and then use that color as your text color.  But I could be misunderstanding the entire issue... here.  You might be wanting to use dynamicTextures for something OTHER-THAN text (such as lines, circles, strokes, etc).  But, fills is fills, right?

 

The context2D object that lies behind dynamicTextures... is a real sweetheart.  Lots of knobs to play-with.  Essentially, SVG on a stick.  :)  Have you looked at that beast?  It is the basis of our drawtext func.  Caution:  People have toured that 2d context webpage... and never returned.  :o

 

Thank goodness context2D is a DOM object and not a BJS object... so we don't have the task of debugging it, ever.  heh

 

But yeah, you can do createPlane, createGround (both gen standard UVs), or plot a plane with vertex data (and still set basic UVs)... then use a STANDARD material on it, and then use a dynamicTexture in one or more of the StandardMaterial's texture-able slots... diffuseTexture, ambientTexture, emissiveTexture, opacityTexture, specularTexture, etc.  It takes a little while to learn how BJS wrangles textures, but once you get comfortable with it, you'll love it.  Mega-versatile.

Link to post
Share on other sites

My script is not easy to read, as I had to remove most remarks to optimize for the node.js server - until I upgrade to mass users today.  If you see I create a ground object, a canvas for a 1024 texture, and a 16x16 canvas as a mask.  I'm able to draw on the ground object, but have been unable to draw on a plane in BJS.  This is not a huge issue now, as I've been able to manipulate the camera to orient the ground to be framed the way I need.  However, it would be good to know why I'm not able to replace the ground object with another object to draw directly on the object.  No text, simply passing pointer events through the texture and mask canvas' to the dynamic texture on the ground.

Link to post
Share on other sites

Hi DB... I want to help with this if I can... but I'm not sure how.  Allow me to try to clarify?

 

When you say "draw on the ground object", you mean... like... dynamicTexture.getContext().lineTo()... for example?

 

Sorry if I'm being rudimentary, here.  You are a pretty smart chap, and it's a challenge for my brain to keep-up with yours, whatsoever.  :)

 

I assume that the mask texture is some crosshairs and/or brush shape.  Correct me as needed.

 

There is nothing better for getting click points on grounds... then the code used by Deltakosh in our drag'n'drop playground demo.  Notice the getGroundPosition() function.  I don't understand the word 'predicate' much at all, but see the return mesh == ground; out on the end of line 66?  That ensures that getGroundPosition returns pickinfo.pickedPoint only when a mesh named 'ground' is clicked-upon.

 

Here's a modification of that demo... and you can see in line 12... that I have changed createGround to createPlane.  Drag'n'drop is still working, so standard planes CAN use pointer pick/click positions.  I suggest using this method or similar.  If you want to create your own plane primitive, just steal the createPlane code (on the vertexData obj) and do your plane in a similar fashion (adjusting positions as wanted).  Keep in mind that there is also a createPlane() func on BABYLON.Mesh, which is a wrapper func for the createPlane() on vertexData.

 

This demo also has starting and ending points, so it is ready for dynamicTexture.getContext().lineTo()... right?

 

Anyway, I hope this helps.  If not, could you use the modified demo, and adjust it in a way that more-clearly shows the issue?  (then make another SAVE and send us the URL)  Thanks!  

 

Sorry it took me so long to respond.  You are probably WAY beyond this issue, by now.  :)  Be well!

Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
  • Recently Browsing   0 members

    No registered users viewing this page.

×
×
  • Create New...