Jump to content

gord0

Members
  • Content count

    36
  • Joined

  • Last visited

  • Days Won

    2

Posts posted by gord0


  1. New oddity I'm dealing with now... how is it possible for a pb_Object's faces to become null even though the object visibly has all of it's faces (cube)? I'm not removing/deleting faces.

    for (int jFace = 0; jFace < _ourPBCube.faces.Length; jFace++)
    {
      if (_ourPBCube.faces[jFace]==null)
      {
        Debug.LogWarning("EGADS!!!");
      }          
    }

     


  2. Turns out, due to unknown sorcery, that the first 6 values in msh.triangles were being removed. So then I manually replaced them and the face reappeared, but was removed again any time I changed anything in the geometry. So I just manually made a new face and appended it to the mesh and set it's vertices to be the same as the missing face. This fix stuck, so that's that I guess.


  3. Well of course because people love changing things, the whole input style has changed. The want to be able to just place nodes and have the "corridors" just connect the nodes. Which is fine, but it also means a lot of how I was doing things has changed. Have you ever had a face just disappear after an extrusion? In this case, not even the face I had extruded.

    1.thumb.png.4244edd34724481f8cf07dba49aebbda.png

    2.png.b75a675534aa801b75feb7be3a57fe84.png


  4. One more thing. When using AppendFace() is there a way to make the face physically stay where it was before appending. It seems to always go to the origin of the pbo that I attach it to. I then have to move the vertices manually with offsets depending where I intended to attach it. Which was fine until I realized that if the pbo is rotated at all it throws everything out of whack.


  5. On ‎10‎/‎04‎/‎2018 at 4:29 PM, karl said:

    The problem stems from how you're creating that initial face. The gist of it is that for the moment it assumes any triangle edge with unique vertex positions are perimeter edges. So when you extrude, ProBuilder thinks that the face you're extruding from is actually two faces. To fix this, just use 4 vertex positions instead of 6. Ex:

    
    		/**
    		 * Vertex positions for a quad are laid out like this. Note that positions 0 & 3 are reused.
    		 *
    		 * 2-----3
    		 * |     |
    		 * |     |
    		 * 0-----1
    		 *
    		 */
    		Vector3[] verts = new Vector3[4]
    		{
    			new Vector3(-1, -1f, 0f),
    			new Vector3( 1, -1f, 0f),
    			new Vector3(-1,  1f, 0f),
    			new Vector3( 1,  1f, 0f),
    		};
    
    		/**
    		 * Quad is two tris:
    		 *
    		 * 2←-------3
    		 * |↖ ↘    ↑
    		 * |  ↖ ↘  |
    		 * ↓    ↖ ↘|
    		 * 0-------→1
    		 */
    		var face = new pb_Face(new int[6]
    		{
    			0, 1, 2,
    			1, 3, 2
    		});
    
    		face.material = pb_Constant.DefaultMaterial;
    		var pb = pb_Object.CreateInstanceWithVerticesFaces(verts, new pb_Face[] { face });
    		pb.ToMesh();
    		pb.Refresh();

     

    It is working! I still have to make some adjustments so that it works on all axis but 4 of the 6 are working. I'll let you know if I have any more questions/troubles. : ]


  6. 3 minutes ago, karl said:

    The problem stems from how you're creating that initial face. The gist of it is that for the moment it assumes any triangle edge with unique vertex positions are perimeter edges. So when you extrude, ProBuilder thinks that the face you're extruding from is actually two faces. To fix this, just use 4 vertex positions instead of 6. Ex:

    
    		/**
    		 * Vertex positions for a quad are laid out like this. Note that positions 0 & 3 are reused.
    		 *
    		 * 2-----3
    		 * |     |
    		 * |     |
    		 * 0-----1
    		 *
    		 */
    		Vector3[] verts = new Vector3[4]
    		{
    			new Vector3(-1, -1f, 0f),
    			new Vector3( 1, -1f, 0f),
    			new Vector3(-1,  1f, 0f),
    			new Vector3( 1,  1f, 0f),
    		};
    
    		/**
    		 * Quad is two tris:
    		 *
    		 * 2←-------3
    		 * |↖ ↘    ↑
    		 * |  ↖ ↘  |
    		 * ↓    ↖ ↘|
    		 * 0-------→1
    		 */
    		var face = new pb_Face(new int[6]
    		{
    			0, 1, 2,
    			1, 3, 2
    		});
    
    		face.material = pb_Constant.DefaultMaterial;
    		var pb = pb_Object.CreateInstanceWithVerticesFaces(verts, new pb_Face[] { face });
    		pb.ToMesh();
    		pb.Refresh();

     

    Cheers, will try this out in the morning. : ]


  7. 59 minutes ago, karl said:

    Okay, so the face that you're extruding from is two triangles then. What is the code that is creating the initial cube or face from which you extrude?

     protected void DrawCustomPlane()
        {
            if (Input.GetMouseButtonUp(0)) //they let go of the button, lets get outta here
            {
                _customExtruding = false;
                _meoc.RelinquishNonAxisMovement = false;
                _specifiedFaceSelect = true;
                CommenceModifications();
                return;
            }
            if (!Input.GetKey(KeyCode.LeftControl)) { return; } //they're not holding left control, so let's chill
    
            if (_customExtruderPlane==null) //if our plane is null
            {
                _ray = _cam.ScreenPointToRay(Input.mousePosition); //let's fire a ray to see if we can fix that
                if (Physics.Raycast(_ray, out _hit, Mathf.Infinity, _lm)) //if we hit something
                {
                    if (_hit.collider.gameObject.GetComponent<pb_Object>()==null) { return; } //forget it, not pb object
    
                    Vector3[] verts = new Vector3[6] //we'll start with all the vertices zero'd out
                    {
                        Vector3.zero,
                        Vector3.zero,
                        Vector3.zero,
                        Vector3.zero,
                        Vector3.zero,
                        Vector3.zero
                    };
                    int[] indices = new int[verts.Length]; //define our indices
                    for (int iVert=0; iVert<verts.Length; iVert++) { indices[iVert] = iVert; } //..
    
                    //now we can make the plane
                    _customExtruderPlane = pb_Object.CreateInstanceWithVerticesFaces(verts, new pb_Face[] { new pb_Face(indices) });
                    _customExtruderPlane.SetFaceMaterial(_customExtruderPlane.faces, PreviewMaterial);
                    _customExtruderPlane.ToMesh();
                    _customExtruderPlane.Refresh();
    
                    //move it just a little in front of whatever the ray hit so we can see it proper
                    _customExtruderPlane.gameObject.transform.position = _hit.point + (_hit.normal * 0.1f);
                    _customExtruderPlane.gameObject.transform.forward = _hit.normal;
                }
            }
    
            if (_customExtruderPlane==null) { return; } //i guess we missed
            else //lets move our vertices according to mouse movement
            {
                /*
                verts[0] -- upper left corner       verts[0] -- upper left corner
                verts[1,3] -- lower left corner     verts[2,3] -- lower left corner
                verts[2,5] -- upper right corner    verts[1,4] -- upper right corner
                verts[4] -- lower right corner      verts[5] -- lower righ corner
    
                0   ---  2,5                        0   ---  1,4
                |        |                          |        |
                |        |                          |        |
                |        |                          |        |
                1,3 ---  4                          2,3 ---  5
    
                */
    
                _ray = _cam.ScreenPointToRay(Input.mousePosition);
                if (Physics.Raycast(_ray, out _hit, Mathf.Infinity, _lm)) //fire ray from the mouse
                {
                    if (_hit.collider.gameObject.GetComponent<pb_Object>() == null) { return; } //forget it, not pb object
    
                    _customPlaneMarker.position = _hit.point; //place our marker at the hit point
                    _customPlaneMarker.parent = _customExtruderPlane.gameObject.transform; //child it to the plane
    
                    Vector3[] verts = _customExtruderPlane.vertices; //grab verts from the plane
    
                    verts[4] = _customPlaneMarker.localPosition; //place lower right corner at marker
                    verts[4].z = verts[0].z; //copy z from upper right corner to lower left (remember plane is a little in front of hit)
                    verts[2].x = verts[4].x; //make rest of verts form the rest of the rectangle based on 0 and 4
                    verts[5].x = verts[4].x; //..
                    verts[1].y = verts[4].y; //..
                    verts[3].y = verts[4].y; //..
    
                    //same as above but clockwise winding order
                    //verts[5] = _customPlaneMarker.localPosition;
                    //verts[5].z = verts[0].z;
                    //verts[1].x = verts[5].x;
                    //verts[4].x = verts[5].x;
                    //verts[2].y = verts[5].y;
                    //verts[3].y = verts[5].y;
    
                    _customExtruderPlane.SetVertices(verts); //update the plane's vertices with our changes
                    _customExtruderPlane.ToMesh(); //apply changes
                    _customExtruderPlane.Refresh(); //..
    
                    _customPlaneMarker.parent = null; //unchild marker from plane
                }
            }
        }

    This is the code that allows the user to draw their own plane.


  8. 17 hours ago, karl said:

    Yup, your only problem is the ExtrudeMethod being used. You want `ExtrudeMethod.FaceNormal`, not InvdividualFaces.

    
    _currentSelection.PB.Extrude(new pb_Face[] { _currentSelection.Face },
                                 ExtrudeMethod.FaceNormal,
                                 !_specifiedFaceSelect ? Mathf.Epsilon : 0.0f); //epsilon if not custom face, otherwise 0

     

    I was hopeful but...same issue. I also tried VertexNormal just see what would happen and it's also the same. All three methods seem to turn out the same in this scenario.


  9. 11 minutes ago, karl said:

    Yup, your only problem is the ExtrudeMethod being used. You want `ExtrudeMethod.FaceNormal`, not InvdividualFaces.

    
    _currentSelection.PB.Extrude(new pb_Face[] { _currentSelection.Face },
                                 ExtrudeMethod.FaceNormal,
                                 !_specifiedFaceSelect ? Mathf.Epsilon : 0.0f); //epsilon if not custom face, otherwise 0

     

    Ahhhh, I didn't even think to look there since I had been using that line as is for so long. Will give it a go in the morning!


  10. Alright I'm getting better results using a different approach. The new problem is, what is this diagonal plain on the inside of the "corridor"? I've used a 2 sided transparent material so you can see (it seems your attachment system is broken so I'm using external links):

    https://pasteboard.co/HfQ4Xja.png

    https://pasteboard.co/HfQ5Ahq.png

     

    This is how I'm achieving it:

    protected void CommenceModifications()
        {
            Vector3 facePos = FaceCenter(_currentSelection.Face, _currentSelection.PB); //get the center point of selected face
            Vector3 toWidget = (_widget.localPosition - facePos).normalized; //get direction from face center to widget
            bool behind = Mathf.Approximately(Vector3.Dot(toWidget, _localNormal), -1.0f); //determine if widget is in front or behind face
    
            if (_canExtrude) //may we extrude?
            {
                //make it so
                _currentSelection.PB.Extrude(new pb_Face[] { _currentSelection.Face },
                                             ExtrudeMethod.IndividualFaces,
                                             !_specifiedFaceSelect ? Mathf.Epsilon : 0.0f); //epsilon if not custom face, otherwise 0
                _currentSelection.PB.ToMesh();
                _currentSelection.PB.Refresh();
    
                if (_specifiedFaceSelect) //is this a user defined face?
                {
                    //move their plane back to be flush with the actual face they want to extrude from
                    _customExtruderPlane.gameObject.transform.position -=
                                                                _customExtruderPlane.gameObject.transform.forward * 0.1f;
    
                    Transform t = _customExtruderPlane.gameObject.transform;
                    if (Mathf.Approximately(t.forward.z, 1.0f) || Mathf.Approximately(t.forward.x, 1.0f) ||
                        Mathf.Approximately(t.forward.x, -1.0f) || Mathf.Approximately(t.forward.y, 1.0f) ||
                        Mathf.Approximately(t.forward.y, -1.0f))
                    {
                        _customExtruderPlane.faces[0].ReverseIndices();
                    }
                    t.parent = _currentSelection.PB.gameObject.transform;
    
                    Vector3[] offSetVerts = _customExtruderPlane.vertices;
                    float xDist = Vector3.Distance(offSetVerts[0], offSetVerts[2]);
                    float yDist = Vector3.Distance(offSetVerts[0], offSetVerts[1]);
                    for (int iVert=0; iVert<offSetVerts.Length; iVert++)
                    {
                        offSetVerts[iVert] += t.localPosition;
                        if (Mathf.Approximately(t.forward.z, -1.0f)) { offSetVerts[iVert].x += xDist; }
                        
                        /*if (iVert==5) //touching: 0, 2, 5
                        {         //not touching: 1, 3, 4
                            Transform go = GameObject.CreatePrimitive(PrimitiveType.Sphere).transform;
                            go.parent = _currentSelection.PB.gameObject.transform;
                            go.localPosition = offSetVerts[iVert];
                        }*/
                        if ((iVert!=0 && iVert!=1 && iVert!=3) &&
                                 (Mathf.Approximately(t.forward.x, 1.0f) || Mathf.Approximately(t.forward.x, -1.0f)))
                        {
                            offSetVerts[iVert].x = offSetVerts[0].x;
                            offSetVerts[iVert].z += xDist * (Mathf.Approximately(t.forward.x, -1.0f) ? -1.0f : 1.0f);
                        }
                        if ((iVert!=0 && iVert!=2 && iVert!=5) &&
                            (Mathf.Approximately(t.forward.y, 1.0f) ||Mathf.Approximately(t.forward.y, -1.0f)))
                        {
                            offSetVerts[iVert].y = offSetVerts[0].y;
                            offSetVerts[iVert].z += yDist * (Mathf.Approximately(t.forward.y, 1.0f) ? -1.0f : 1.0f);
                        }
                    }
                    t.parent = null;
    
                    pb_Face pbf=_currentSelection.PB.AppendFace(offSetVerts,
                                                                new Color[1] { Color.white },
                                                                _customExtruderPlane.uv,
                                                                _customExtruderPlane.faces[0]);
    
                    _manualFaceSelect = true;
                    _manualFaceSelectPBO = _currentSelection.PB;
                    _manualFaceSelectFace = pbf;
    
                    /*Debug.LogWarning("_customExtruderPlane.gameObject.transform.forward: " + 
                                      _customExtruderPlane.gameObject.transform.forward);*/
    
                    if (_customExtruderPlane != null) { Destroy(_customExtruderPlane.gameObject); }
                }
    
                _currentSelection.PB.ToMesh(); //apply changes
                _currentSelection.PB.Refresh(); //..       
                _canExtrude = false; //no more extuding for now
            }
    
            if (!_specifiedFaceSelect) //if this was a not a user defined face, translate the verts based on widget pos
            {
                _currentSelection.PB.TranslateVertices(
                        _currentSelection.Face.distinctIndices,
                        _localNormal.normalized * (Vector3.Distance(_widget.localPosition, facePos)) * (behind ? -1.0f : 1.0f)
                                                      );
                _currentSelection.PB.ToMesh();
                _currentSelection.PB.Refresh();
            }
            else //otherwise
            {
                _specifiedFaceSelect = false; //we're done with the user defined face
                _destroyPreview = true; //destroy the preview plane
                _waitAFrame = true; //we should probably wait a frame before we do anything else
            }
    
            // Refresh will update the Collision mesh volume, face UVs as applicatble, and normal information.
            _currentSelection.PB.Refresh();
    
            // this creates the selected face preview
            RefreshSelectedFacePreview();

    Have you seen this kind of problem before?


  11. 19 hours ago, karl said:

    Yes, precisely. It seems like you've got the parts mostly correct, now it's just a matter of making sure that the pb_Object mesh state is set after you do the modifications. So looking at this as an example you can parse out when the appropriate times to call Extrude, ToMesh, and Refresh.

    I've added a couple more ToMesh() and Refesh()es so that each time I Extrude(), SetVertices(), ReverseIndices(), and TranslateVertices() I call those two methods immediately after. Seems to have been redundant though because my result is the same as before :(

        protected void CommenceModifications()
        {
            Vector3 facePos = FaceCenter(_currentSelection.Face, _currentSelection.PB); //get the center point of selected face
            Vector3 toWidget = (_widget.localPosition - facePos).normalized; //get direction from face center to widget
            bool behind = Mathf.Approximately(Vector3.Dot(toWidget, _localNormal), -1.0f); //determine if widget is in front or behind face
    
            if (_canExtrude) //may we extrude?
            {
                //make it so
                _currentSelection.PB.Extrude(new pb_Face[] { _currentSelection.Face },
                                             ExtrudeMethod.IndividualFaces,
                                             !_specifiedFaceSelect ? Mathf.Epsilon : 0.0f); //epsilon if not custom face, otherwise 0
                _currentSelection.PB.ToMesh();
                _currentSelection.PB.Refresh();
    
                if (_specifiedFaceSelect) //is this a user defined face?
                {
                    //move their plane back to be flush with the actual face they want to extrude from
                    _customExtruderPlane.gameObject.transform.position -=
                                                                    _customExtruderPlane.gameObject.transform.forward * 0.1f;
    
                    //extrude again with 0 distance
                    _currentSelection.PB.Extrude(new pb_Face[] { _currentSelection.Face },
                                             ExtrudeMethod.IndividualFaces,
                                             0.0f);
                    _currentSelection.PB.ToMesh();
                    _currentSelection.PB.Refresh();
    
                    Vector3[] verts = _currentSelection.PB.vertices; //grab all our verts
                    int[] indices = _currentSelection.Face.indices /*distinctIndices*/; //grab the indices of the current face
                    Vector3[] toVerts = _customExtruderPlane.vertices; //grab the verts of the user defined plane
    
                    //place markers to represent the postions of the user defined plane verts
                    for (int iMarker = 0; iMarker < _faceScalerMarkers.Length; iMarker++)
                    {
                        //child marker to user defined plane
                        _faceScalerMarkers[iMarker].parent = _customExtruderPlane.gameObject.transform;
                        //place marker at user defined plane's iMarker vertice position
                        _faceScalerMarkers[iMarker].localPosition = toVerts[iMarker];
                        _faceScalerMarkers[iMarker].parent = transform; //child marker to us
                    }
    
                    //set current face vertices to the position of the closest marker (to retain wind order)
                    for (int iVert = 0; iVert < indices.Length; iVert++)
                    {
                        verts[indices[iVert]] = ClosestScalerMarkerPos(verts[indices[iVert]]);
                    }
                    _currentSelection.PB.SetVertices(verts); //apply new vertice positions
                    _currentSelection.PB.ToMesh();
                    _currentSelection.PB.Refresh();
                    _currentSelection.Face.ReverseIndices(); //reverse the indices so we can see the face (for some reason backwards)
                    _currentSelection.PB.ToMesh();
                    _currentSelection.PB.Refresh();
    
                    Destroy(_customExtruderPlane.gameObject); //destroy user defined plane
    
                    for (int iMarker = 0; iMarker < _faceScalerMarkers.Length; iMarker++) //unchild markers
                    {
                        _faceScalerMarkers[iMarker].parent = null;
                    }
                }
    
                _currentSelection.PB.ToMesh(); //apply changes
                _currentSelection.PB.Refresh(); //..       
                _canExtrude = false; //no more extuding for now
            }
    
            if (!_specifiedFaceSelect) //if this was a not a user defined face, translate the verts based on widget pos
            {
                _currentSelection.PB.TranslateVertices(
                        _currentSelection.Face.distinctIndices,
                        _localNormal.normalized * (Vector3.Distance(_widget.localPosition, facePos)) * (behind ? -1.0f : 1.0f)
                                                      );
                _currentSelection.PB.ToMesh();
                _currentSelection.PB.Refresh();
            }
            else //otherwise
            {
                _specifiedFaceSelect = false; //we're done with the user defined face
                _destroyPreview = true; //destroy the preview plane
                _waitAFrame = true; //we should probably wait a frame before we do anything else
            }
    
            // Refresh will update the Collision mesh volume, face UVs as applicatble, and normal information.
            _currentSelection.PB.Refresh();
    
            // this creates the selected face preview
            RefreshSelectedFacePreview();
        }

     


  12. Sorry, I was off work longer than I knew I was going to be. Anyway, I've got that project opened up. It didn't have the probuilder stuff with it so I imported it. After that I now have " The type or namespace name `Math' does not exist in the namespace `ProBuilder2'. Are you missing an assembly reference?" coming from Pipe.cs on line 5:

    using ProBuilder2.Math;

    If I comment that out, the next problem is "The name `pb_Shape_Generator' does not exist in the current context" coming from PipeSpawner.cs at line 238:

    pb_Object pb = pb_Shape_Generator.CubeGenerator(Vector3.one * pipeSize);

    I imagine this is due to deprecation? How might I sort this out?


  13. 3 minutes ago, karl said:

    Can you condense the code to the specific problem area? It would be much easier for me to help pick out the issue.

    Yes, you can merge meshes using the MeshOps namespace.

    I'm not at work today, but the problem is most likely in CommenceModifications().

    The reason I asked about a merging functionality is that it could probably take a huge chunk of the work out of my hands. If I were to place a plane on a face of a cube, said plane is smaller dimensions than the face, and merge would that plane become a face on the cube?


  14. I'm super stuck. Don't know how to sort this out.

    Does probuilder have the ability to "merge" meshes? So I could just merge the user drawn plane (pb_Object) into the target object (pb_Object) so that I don't have to do all this manual jiggering around? Or do you know another way to achieve the desired result?


  15. Alright, so nothing in there really helps (that I can tell).

    So right now I've got it doing almost what I want but I'm experiencing geometry glitches. I've stripped out as much of my project as I could while keeping code in question functioning and placed it in a zip which I've attached to this post (CorridorTest3.7z).

    The code that's doing the work in question is in PBCorridor.cs .

    The scene is PBCorridorTest3 .

    You'll need to be quite careful as I've only put in super basic functionality and it's easy to break things.

    First you'll want to drag out a corridor:

    dragPallete.png.0aab0cad8cb818f0d77f8e0a078e4106.png

    It should look like this, don't click anywhere just yet:

    0.png.573b2af3a8145ba0394c7d20c2c2e716.png

    Now move the cursor to somewhere  on the face that is facing the camera. Hold left control and left click and drag the mouse to draw a rectangle on the face (might want to have left control down before the left click):

    1.png.02477a2beff4e554c1ba19d6ed11fad9.png

    When you let go, the rectangle will disappear (at least for now it does, later I'll have it auto-select). Click roughly near the center of the rectangle you drew. A single arrow should appear with your rectangle highlighted:

    2.png.f335f6c1b0ec0578b0c15084add5a9ab.png

    Now you'll want to move the camera to see better (camera controls are same as scene view (right click--rotate, middle mouse down--pan/strafe, scroll wheel--zoom). Then left click on arrow and pull it:

    3.png.f69098151798587e4c5c391c5fd99d37.png

     

    Now you're thinking, so you've got it. What's the problem? Well if you try this on any other face (including a second time on the face you already used) the geometry gets messed up causing faces to no longer be visible. Also, in the screen shot above, it actually has one tiny problem too (the face on the back side that is not in view of the camera is invisible).

    This is the point where I no longer know what to do.

    Any help would be much appreciated. : ]


  16. On ‎23‎/‎03‎/‎2018 at 6:48 PM, karl said:

    If you've not already found it, you may find our repository of example code helpful. https://github.com/Unity-Technologies/ProBuilder-API-Examples

     

    Just got back in from the weekend. I see you've added more stuff to the repo since I last visited a week or two ago. I've made some progress on my side but still stuck with some things. I'll take a look on the repo and report back later.

×