public static void DrawCornerLinesForSelectionBoxes(List <ObjectSelectionBox> selectionBoxes, float boxSizeAdd, float cornerLinePercentage, Camera camera, Color cornerLineColor, Material boxLineMaterial) { // Save the current modelview matrix. We will always modify the model view matrix such that it // represents the result of the multiplication between the box's transform matrix and the camera // view matrix. GL.PushMatrix(); // Apply the material boxLineMaterial.SetColor("_Color", cornerLineColor); boxLineMaterial.SetPass(0); // Unity uses a left handed coordinate system, but the GL API expects us to work // with matrices whose transforms are relative to a right handed coordinate system. // So, we will need to multiply our modelview matrix with another matrix which makes // sure that the final resulting matrix represents the same transform but in a right // handed coordinate system. We do this simply by negating the sign of the Z value // inside an identity matrix. Matrix4x4 toRightHanded = Matrix4x4.identity; toRightHanded[2, 2] *= -1.0f; // Store the inverse camera transform for easy access Matrix4x4 cameraInverseTransform = camera.transform.worldToLocalMatrix; // Loop through each box and render it for (int selectionBoxIndex = 0; selectionBoxIndex < selectionBoxes.Count; ++selectionBoxIndex) { // Store box for easy access ObjectSelectionBox objectSelectionBox = selectionBoxes[selectionBoxIndex]; // Store the model space box and box transform matrix for easy access Box modelSpaceBox = objectSelectionBox.ModelSpaceBox; Matrix4x4 boxTransformMatrix = objectSelectionBox.TransformMatrix; modelSpaceBox.Size += Vector3.one * boxSizeAdd; Vector3 matrixScale = boxTransformMatrix.GetXYZScale(); modelSpaceBox.Size = Vector3.Scale(modelSpaceBox.Size, matrixScale); modelSpaceBox.Center = Vector3.Scale(modelSpaceBox.Center, matrixScale); boxTransformMatrix = boxTransformMatrix.SetScaleToOneOnAllAxes(); // Set the corrent modelview matrix. // Note: In order to construct the modelview matrix, we multiply the box world transform // with the camera view matrix (given to us by 'camera.transform.worldToLocalMatrix'), // and then, we perform a final multiplication with the 'toRightHanded' matrix in order // to ensure that the resulting matrix contains a transform which exists inside a // right handed coordinate system. This is what the GL API expects. GL.LoadIdentity(); GL.MultMatrix(toRightHanded * cameraInverseTransform * boxTransformMatrix); // Begin drawing GL.Begin(GL.LINES); // Set the color used to draw the box lines GL.Color(cornerLineColor); // Make sure the corner line length does not exceed the half size of the box on any axis. float lineLengthAlongX = cornerLinePercentage * modelSpaceBox.Extents.x; float lineLengthAlongY = cornerLinePercentage * modelSpaceBox.Extents.y; float lineLengthAlongZ = cornerLinePercentage * modelSpaceBox.Extents.z; // Top left corner in front face Vector3 startPoint = new Vector3(modelSpaceBox.Min.x, modelSpaceBox.Max.y, modelSpaceBox.Min.z); Vector3 endPoint = startPoint + Vector3.right * lineLengthAlongX; GL.Vertex(startPoint); GL.Vertex(endPoint); endPoint = startPoint - Vector3.up * lineLengthAlongY; GL.Vertex(startPoint); GL.Vertex(endPoint); endPoint = startPoint + Vector3.forward * lineLengthAlongZ; GL.Vertex(startPoint); GL.Vertex(endPoint); // Top right corner in front face startPoint = new Vector3(modelSpaceBox.Max.x, modelSpaceBox.Max.y, modelSpaceBox.Min.z); endPoint = startPoint - Vector3.right * lineLengthAlongX; GL.Vertex(startPoint); GL.Vertex(endPoint); endPoint = startPoint - Vector3.up * lineLengthAlongY; GL.Vertex(startPoint); GL.Vertex(endPoint); endPoint = startPoint + Vector3.forward * lineLengthAlongZ; GL.Vertex(startPoint); GL.Vertex(endPoint); // Bottom right corner in front face startPoint = new Vector3(modelSpaceBox.Max.x, modelSpaceBox.Min.y, modelSpaceBox.Min.z); endPoint = startPoint - Vector3.right * lineLengthAlongX; GL.Vertex(startPoint); GL.Vertex(endPoint); endPoint = startPoint + Vector3.up * lineLengthAlongY; GL.Vertex(startPoint); GL.Vertex(endPoint); endPoint = startPoint + Vector3.forward * lineLengthAlongZ; GL.Vertex(startPoint); GL.Vertex(endPoint); // Bottom left corner in front face startPoint = new Vector3(modelSpaceBox.Min.x, modelSpaceBox.Min.y, modelSpaceBox.Min.z); endPoint = startPoint + Vector3.right * lineLengthAlongX; GL.Vertex(startPoint); GL.Vertex(endPoint); endPoint = startPoint + Vector3.up * lineLengthAlongY; GL.Vertex(startPoint); GL.Vertex(endPoint); endPoint = startPoint + Vector3.forward * lineLengthAlongZ; GL.Vertex(startPoint); GL.Vertex(endPoint); // Top left corner in back face startPoint = new Vector3(modelSpaceBox.Min.x, modelSpaceBox.Max.y, modelSpaceBox.Max.z); endPoint = startPoint + Vector3.right * lineLengthAlongX; GL.Vertex(startPoint); GL.Vertex(endPoint); endPoint = startPoint - Vector3.up * lineLengthAlongY; GL.Vertex(startPoint); GL.Vertex(endPoint); endPoint = startPoint - Vector3.forward * lineLengthAlongZ; GL.Vertex(startPoint); GL.Vertex(endPoint); // Top right corner in back face startPoint = new Vector3(modelSpaceBox.Max.x, modelSpaceBox.Max.y, modelSpaceBox.Max.z); endPoint = startPoint - Vector3.right * lineLengthAlongX; GL.Vertex(startPoint); GL.Vertex(endPoint); endPoint = startPoint - Vector3.up * lineLengthAlongY; GL.Vertex(startPoint); GL.Vertex(endPoint); endPoint = startPoint - Vector3.forward * lineLengthAlongZ; GL.Vertex(startPoint); GL.Vertex(endPoint); // Bottom right corner in back face startPoint = new Vector3(modelSpaceBox.Max.x, modelSpaceBox.Min.y, modelSpaceBox.Max.z); endPoint = startPoint - Vector3.right * lineLengthAlongX; GL.Vertex(startPoint); GL.Vertex(endPoint); endPoint = startPoint + Vector3.up * lineLengthAlongY; GL.Vertex(startPoint); GL.Vertex(endPoint); endPoint = startPoint - Vector3.forward * lineLengthAlongZ; GL.Vertex(startPoint); GL.Vertex(endPoint); // Bottom left corner in back face startPoint = new Vector3(modelSpaceBox.Min.x, modelSpaceBox.Min.y, modelSpaceBox.Max.z); endPoint = startPoint + Vector3.right * lineLengthAlongX; GL.Vertex(startPoint); GL.Vertex(endPoint); endPoint = startPoint + Vector3.up * lineLengthAlongY; GL.Vertex(startPoint); GL.Vertex(endPoint); endPoint = startPoint - Vector3.forward * lineLengthAlongZ; GL.Vertex(startPoint); GL.Vertex(endPoint); // End drawing for the current box GL.End(); } // Restore the old modelview matrix GL.PopMatrix(); }
public static void DrawWireSelectionBoxes(List <ObjectSelectionBox> selectionBoxes, float boxSizeAdd, Camera camera, Color lineColor, Material boxLineMaterial) { // Save the current modelview matrix. We will always modify the model view matrix such that it // represents the result of the multiplication between the box's transform matrix and the camera // view matrix. GL.PushMatrix(); // Apply the material boxLineMaterial.SetColor("_Color", lineColor); boxLineMaterial.SetPass(0); // Unity uses a left handed coordinate system, but the GL API expects us to work // with matrices whose transforms are relative to a right handed coordinate system. // So, we will need to multiply our modelview matrix with another matrix which makes // sure that the final resulting matrix represents the same transform but in a right // handed coordinate system. We do this simply by negating the sign of the Z value // inside an identity matrix. Matrix4x4 toRightHanded = Matrix4x4.identity; toRightHanded[2, 2] *= -1.0f; // Store the inverse camera transform for easy access Matrix4x4 cameraInverseTransform = camera.transform.worldToLocalMatrix; // Loop through each box and render it for (int selectionBoxIndex = 0; selectionBoxIndex < selectionBoxes.Count; ++selectionBoxIndex) { // Store box for easy access ObjectSelectionBox objectSelectionBox = selectionBoxes[selectionBoxIndex]; // Store the model space box and box transform matrix for easy access Box modelSpaceBox = objectSelectionBox.ModelSpaceBox; Matrix4x4 boxTransformMatrix = objectSelectionBox.TransformMatrix; modelSpaceBox.Size += Vector3.one * boxSizeAdd; // Set the corrent modelview matrix. // Note: In order to construct the modelview matrix, we multiply the box world transform // with the camera view matrix (given to us by 'camera.transform.worldToLocalMatrix'), // and then, we perform a final multiplication with the 'toRightHanded' matrix in order // to ensure that the resulting matrix contains a transform which exists inside a // right handed coordinate system. This is what the GL API expects. GL.LoadIdentity(); GL.MultMatrix(toRightHanded * cameraInverseTransform * boxTransformMatrix); // Begin drawing for the current box GL.Begin(GL.LINES); // Set the color used to draw the box lines GL.Color(lineColor); // Front face GL.Vertex3(modelSpaceBox.Min.x, modelSpaceBox.Min.y, modelSpaceBox.Min.z); GL.Vertex3(modelSpaceBox.Max.x, modelSpaceBox.Min.y, modelSpaceBox.Min.z); GL.Vertex3(modelSpaceBox.Max.x, modelSpaceBox.Min.y, modelSpaceBox.Min.z); GL.Vertex3(modelSpaceBox.Max.x, modelSpaceBox.Max.y, modelSpaceBox.Min.z); GL.Vertex3(modelSpaceBox.Max.x, modelSpaceBox.Max.y, modelSpaceBox.Min.z); GL.Vertex3(modelSpaceBox.Min.x, modelSpaceBox.Max.y, modelSpaceBox.Min.z); GL.Vertex3(modelSpaceBox.Min.x, modelSpaceBox.Max.y, modelSpaceBox.Min.z); GL.Vertex3(modelSpaceBox.Min.x, modelSpaceBox.Min.y, modelSpaceBox.Min.z); // Back face GL.Vertex3(modelSpaceBox.Min.x, modelSpaceBox.Min.y, modelSpaceBox.Max.z); GL.Vertex3(modelSpaceBox.Max.x, modelSpaceBox.Min.y, modelSpaceBox.Max.z); GL.Vertex3(modelSpaceBox.Max.x, modelSpaceBox.Min.y, modelSpaceBox.Max.z); GL.Vertex3(modelSpaceBox.Max.x, modelSpaceBox.Max.y, modelSpaceBox.Max.z); GL.Vertex3(modelSpaceBox.Max.x, modelSpaceBox.Max.y, modelSpaceBox.Max.z); GL.Vertex3(modelSpaceBox.Min.x, modelSpaceBox.Max.y, modelSpaceBox.Max.z); GL.Vertex3(modelSpaceBox.Min.x, modelSpaceBox.Max.y, modelSpaceBox.Max.z); GL.Vertex3(modelSpaceBox.Min.x, modelSpaceBox.Min.y, modelSpaceBox.Max.z); // Bottom face (partially drawn when drawing the front and back faces, so we // will only draw what's left) GL.Vertex3(modelSpaceBox.Min.x, modelSpaceBox.Min.y, modelSpaceBox.Min.z); GL.Vertex3(modelSpaceBox.Min.x, modelSpaceBox.Min.y, modelSpaceBox.Max.z); GL.Vertex3(modelSpaceBox.Max.x, modelSpaceBox.Min.y, modelSpaceBox.Min.z); GL.Vertex3(modelSpaceBox.Max.x, modelSpaceBox.Min.y, modelSpaceBox.Max.z); // Top face (partially drawn when drawing the front and back faces, so we // will only draw what's left) GL.Vertex3(modelSpaceBox.Min.x, modelSpaceBox.Max.y, modelSpaceBox.Min.z); GL.Vertex3(modelSpaceBox.Min.x, modelSpaceBox.Max.y, modelSpaceBox.Max.z); GL.Vertex3(modelSpaceBox.Max.x, modelSpaceBox.Max.y, modelSpaceBox.Min.z); GL.Vertex3(modelSpaceBox.Max.x, modelSpaceBox.Max.y, modelSpaceBox.Max.z); // End drawing for this box GL.End(); } // Restore the old modelview matrix GL.PopMatrix(); }