1 /** 2 Copyright: Copyright (c) 2015-2016 Andrey Penechko. 3 License: $(WEB boost.org/LICENSE_1_0.txt, Boost License 1.0). 4 Authors: Andrey Penechko. 5 */ 6 7 module voxelman.worldinteraction.plugin; 8 9 import std.experimental.logger; 10 import core.time; 11 12 import pluginlib; 13 import voxelman.core.config; 14 15 import voxelman.core.events; 16 import voxelman.core.packets; 17 import voxelman.storage.coordinates; 18 19 import voxelman.input.plugin; 20 import voxelman.eventdispatcher.plugin; 21 import voxelman.graphics.plugin; 22 import voxelman.client.plugin; 23 24 25 shared static this() 26 { 27 pluginRegistry.regClientPlugin(new WorldInteractionPlugin); 28 } 29 30 class WorldInteractionPlugin : IPlugin 31 { 32 ClientPlugin clientPlugin; 33 EventDispatcherPlugin evDispatcher; 34 GraphicsPlugin graphics; 35 36 // Cursor 37 bool cursorHit; 38 BlockWorldPos blockPos; 39 ivec3 hitNormal; 40 41 // Cursor rendering stuff 42 vec3 cursorPos, cursorSize = vec3(1.02, 1.02, 1.02); 43 vec3 lineStart, lineEnd; 44 bool traceVisible; 45 bool showCursor = true; 46 vec3 hitPosition; 47 Duration cursorTraceTime; 48 Batch traceBatch; 49 Batch hitBatch; 50 51 mixin IdAndSemverFrom!(voxelman.worldinteraction.plugininfo); 52 53 override void init(IPluginManager pluginman) 54 { 55 clientPlugin = pluginman.getPlugin!ClientPlugin; 56 evDispatcher = pluginman.getPlugin!EventDispatcherPlugin; 57 graphics = pluginman.getPlugin!GraphicsPlugin; 58 59 evDispatcher.subscribeToEvent(&onUpdateEvent); 60 evDispatcher.subscribeToEvent(&drawDebug); 61 } 62 63 void onUpdateEvent(ref UpdateEvent event) 64 { 65 traceCursor(); 66 drawDebugCursor(); 67 } 68 69 void placeBlock(BlockType blockId) 70 { 71 if (clientPlugin.chunkMan.blockMan.blocks[blockId].isVisible) 72 { 73 blockPos.vector += hitNormal; 74 } 75 76 //infof("hit %s, blockPos %s, hitPosition %s, hitNormal %s\ntime %s", 77 // cursorHit, blockPos, hitPosition, hitNormal, 78 // cursorTraceTime.formatDuration); 79 80 cursorPos = vec3(blockPos.vector) - vec3(0.005, 0.005, 0.005); 81 lineStart = graphics.camera.position; 82 lineEnd = graphics.camera.position + graphics.camera.target * 40; 83 84 if (cursorHit) 85 { 86 hitBatch = traceBatch; 87 traceBatch = Batch(); 88 89 traceVisible = true; 90 clientPlugin.connection.send(PlaceBlockPacket(blockPos.vector, blockId)); 91 } 92 else 93 { 94 traceVisible = false; 95 } 96 } 97 98 BlockType pickBlock() 99 { 100 return clientPlugin.worldAccess.getBlock(blockPos); 101 } 102 103 void traceCursor() 104 { 105 StopWatch sw; 106 sw.start(); 107 108 auto isBlockSolid = (ivec3 blockWorldPos) { 109 auto block = clientPlugin.worldAccess.getBlock(BlockWorldPos(blockWorldPos)); 110 return clientPlugin.chunkMan 111 .blockMan 112 .blocks[block] 113 .isVisible; 114 }; 115 116 traceBatch.reset(); 117 118 cursorHit = traceRay( 119 isBlockSolid, 120 graphics.camera.position, 121 graphics.camera.target, 122 200.0, // max distance 123 hitPosition, 124 hitNormal, 125 traceBatch); 126 127 blockPos = BlockWorldPos(hitPosition); 128 cursorTraceTime = cast(Duration)sw.peek; 129 } 130 131 void drawDebugCursor() 132 { 133 if (traceVisible) 134 { 135 traceBatch.putCube(cursorPos, cursorSize, Colors.black, false); 136 traceBatch.putLine(lineStart, lineEnd, Colors.black); 137 } 138 139 if (showCursor) 140 { 141 graphics.debugBatch.putCube( 142 vec3(blockPos.vector) - vec3(0.005, 0.005, 0.005), 143 cursorSize, Colors.red, false); 144 graphics.debugBatch.putCube( 145 vec3(blockPos.vector+hitNormal) - vec3(0.005, 0.005, 0.005), 146 cursorSize, Colors.blue, false); 147 } 148 } 149 150 void drawDebug(ref Render1Event event) 151 { 152 //graphics.chunkShader.bind; 153 //graphics.draw(hitBatch); 154 //graphics.chunkShader.unbind; 155 } 156 }