Jump to content
• Advertisement  # JD_Rushing

Member

8

373 Neutral

• Rank
Newbie

## Personal Information

• Role
Programmer
• Interests
Art
Design
Programming
1. ## Strange slowdown when model(s) goes off screen

How are you storing and updating your objects?
2. ## Odd issue with Separating Axis Theorem

Without edge testing i was getting false positives.  And the last loop is testing the mix/max for the smallest overlap.  X,Y is min0 and max0.  Z,W is min1, max1.  I don't plan on keeping it like that, as storing the values is definitely not optimized.  It was just for debugging.   Walking passed the "cracks" between 2 oob is apparently a common problem.  I am trying to research and see what I can find.  Although any suggestions on that would be great.   EDIT: I am averaging all the collisions together and then applying the average to the object to move it.  It appears to be working right now with low gravity.  Higher gravity, back to same problem.
3. ## Odd issue with Separating Axis Theorem

Well the code is mostly fixed.  bool Collide(RigidBody* other, Vector4f& collision) { std::vector<Vector3f> axies; std::vector<Vector4f> minmax; int count = 0; float min0, max0; float min1, max1; Vector3f dir; float dist = 10000.f; Vector3f axis; int wAxis = -1; int which = -1; axies.resize(0); minmax.resize(0); Vector3f offset = pos - other->pos; for (count = 0; count < GetFaceSize(); count++) { dir = GetNormal(count); Project(dir, min0, max0); other->Project(dir, min1, max1); if (max0 < min1 || max1 < min0) return false; axies.push_back(dir); minmax.push_back(Vector4f(min0, max0, min1, max1)); } for (count = 0; count < other->GetFaceSize(); count++) { dir = other->GetNormal(count); Project(dir, min0, max0); other->Project(dir, min1, max1); if (max0 < min1 || max1 < min0) return false; axies.push_back(dir); minmax.push_back(Vector4f(min0, max0, min1, max1)); } int counts; for (count = 0; count < GetFaceSize(); count++) { for (counts = 0; counts < other->GetFaceSize(); counts++) { dir = GetNormal(count).CrossProduct(other->GetNormal(counts)); dir.Normalize(); Project(dir, min0, max0); other->Project(dir, min1, max1); if (max0 < min1 || max1 < min0) return false; axies.push_back(dir); minmax.push_back(Vector4f(min0, max0, min1, max1)); } } int aCount = 0; float temp; for (count = 0; count < axies.size(); count++) { if (!axies[count].isEqual(Vector3f(0, 0, 0))) { if ((minmax[count].y - minmax[count].z < minmax[count].w - minmax[count].x) && minmax[count].y > minmax[count].z) { if (dist > minmax[count].y - minmax[count].z) { wAxis = count; axis = axies[count]; dist = minmax[count].y - minmax[count].z; } } else if (minmax[count].w > minmax[count].x) { if (dist > minmax[count].w - minmax[count].x) { wAxis = count; axis = axies[count]; dist = minmax[count].w - minmax[count].x; } } } } if ((pos - other->pos).Dot(axis) < 0) { axis = axis * -1.0f; } collision = Vector4f(axis, dist); return true; } The cross product of the 2 box faces is for edge testing.  And the check for a 0 direction is because cross product of same directions give you a 0.   Ty snake5 on the min/max, that was a problem, and the "touching == true" was unneccessary.   It works mostly.  When two oobs meet, I seem to get caught or pushed out of the hallway.
4. ## Odd issue with Separating Axis Theorem

bool Collide(RigidBody* other, Vector4f& collision) { std::vector<Vector3f> axies; std::vector<Vector4f> minmax; int count = 0; float min0, max0; float min1, max1; Vector3f dir; float dist = 10000.f; Vector3f axis; bool moving = false; bool touching = false; int wAxis = -1; int which = -1; axies.resize(0); minmax.resize(0); for (count = 0; count < GetFaceSize(); count++) { dir = GetNormal(count); Project(dir, min0, max0); other->Project(dir, min1, max1); if (max0 < min1 || max1 < min0) return false; axies.push_back(dir); minmax.push_back(Vector4f(min0, max0, min1, max1)); if (max1 == min0 || max0 == min1) { touching = true; } else { if (max0 > min1 && dir != Vector3f(0, 0, 0)) { if (dist > max0 - min1 && max0 - min1 > 0.0f) { dist = max0 - min1; axis = dir; wAxis = axies.size() - 1; } } else if (dir != Vector3f(0, 0, 0)) { if (dist > max1 - min0 && max1 - min0 > 0.0f) { dist = max1 - min0; axis = dir; wAxis = axies.size() - 1; } } } } for (count = 0; count < other->GetFaceSize(); count++) { dir = other->GetNormal(count); Project(dir, min0, max0); other->Project(dir, min1, max1); if (max0 < min1 || max1 < min0) return false; axies.push_back(dir); minmax.push_back(Vector4f(min0, max0, min1, max1)); if (max1 == min0 || max0 == min1) { touching = true; } else if (max0 > min1 && dir != Vector3f(0, 0, 0)) { if (dist > max0 - min1 && max0 - min1 > 0.0f) { dist = max0 - min1; axis = dir; wAxis = axies.size() - 1; } } else if (dir != Vector3f(0, 0, 0)) { if (dist > max1 - min0 && max1 - min0 > 0.0f) { dist = max1 - min0; axis = dir; wAxis = axies.size() - 1; } } } int counts; for (count = 0; count < GetFaceSize(); count++) { for (counts = 0; counts < other->GetFaceSize(); counts++) { dir = GetNormal(count).CrossProduct(other->GetNormal(counts)); dir.Normalize(); Project(dir, min0, max0); other->Project(dir, min1, max1); if (max0 < min1 || max1 < min0) return false; axies.push_back(dir); minmax.push_back(Vector4f(min0, max0, min1, max1)); if (max1 == min0 || max0 == min1) { touching = true; } else if (max0 > min1 && dir != Vector3f(0, 0, 0)) { if (dist > max0 - min1 && max0 - min1 > 0.0f) { dist = max0 - min1; axis = dir; wAxis = axies.size() - 1; } } else if (dir != Vector3f(0, 0, 0)) { if (dist > max1 - min0 && max1 - min0 > 0.0f) { dist = max1 - min0; axis = dir; wAxis = axies.size() - 1; } } } } if (touching == true && dist > 1000.0f) { dist = 0; } collision = Vector4f(axis * -1.0f, dist); return true; }
5. ## Odd issue with Separating Axis Theorem

I have the collision detection working great.  I have a hallway I generate with a box that moves down it.  I have gravity that will pull the object down when I raise it with [space].  If I turn off collision response, the box will stop if it's next move will collide, every time.  But with collision response on, it will follow most surfaces without penetrating perfectly.  But certain spots of some faces will cause the collision response to tell it to go to an opposing face versus along the face it is against.  Like if it was moving along the face with an -x normal, it will jump to the face with the -y normal instead.  And when I look at the list of axes and min/max, the min/max differences all have a much larger gap that it should.  Has anyone run into anything like this?   The hallway is composed of 4 different OBB, one for each wall.
6. ## Small break, but back to work

I took a break due to work being hectic and everyone seeming to get sick. I added alpha blending and I have working armatures and working on the keyframes to create animations.
7. ## 2d Game Creation

Different screenshots along the way
8. I got rid of most of the slider bars now that I have working color picking and constant buffers. So I decided to try and draw something. I was going for the mysterious woman on the water in a row boat. All the shapes now have visible, clickable, control points. I need to work a little bit more on correct mouse movement translations (you move left but the control moves right). But I was able to accomplish this. Next is armatures for actual animation. [sharedmedia=gallery:images:5804]
9. ## Color Picking, Constant Buffers, and Shaders

FINALLY!!! Constant buffer worked without errors. I guess I kept running into bad examples. Many were missing information. I simply wanted to do color picking and set a constant buffer for the color. So both the color picking and the constant buffer (to set the object/shape to a solid color to be referenced) were a pain. So R - What kinds of pick (gui, object/shape, control point) G - index1 (example - object index) B - index2 (example - shape index) So I finally wrote directx functions that are similar to my opengl counterparts. For now this is my constant buffer (the name is from the msdn example). Vector4f is my own (x, y, z, w). The other is my PixelShader, to which is stored in a vector for multiple shaders.struct VS_CONSTANT_BUFFER{Vector4f modifier;};struct PixelShader{ID3D11PixelShader* shader; ID3D11Buffer* g_pConstantBuffer11;Vector4f modifier;}; This is my AddShader routine. I currently have both my pixel shader and vertex shader in the same file, but left it like this in case I change my mind. I just give the same file name for both pix and vert.Vector2i Shaders::AddShader(ID3D11Device *dev, ID3D11DeviceContext *devcon, char* pix, char* vert){cShade = -1;//The Shaders. cShade holds the index of current shader loaded. -1 means none.pVS.resize(pVS.size() + 1);pPS.resize(pPS.size() + 1);pLayout.resize(pLayout.size() + 1);ID3D10Blob *VS, *PS;HRESULT HRV = D3DX11CompileFromFile(vert, 0, 0, "VShader", "vs_4_0", 0, 0, 0, &VS, 0, 0);HRESULT HRP = D3DX11CompileFromFile(pix, 0, 0, "PShader", "ps_4_0", 0, 0, 0, &PS, 0, 0);//Create the shaders and give the pointers. Vertex currently does not have extra parameters is just a std::vectordev->CreateVertexShader(VS->GetBufferPointer(), VS->GetBufferSize(), NULL, &pVS[pVS.size() - 1]);dev->CreatePixelShader(PS->GetBufferPointer(), PS->GetBufferSize(), NULL, &pPS[pPS.size() - 1].shader);//Each time the shaders are set, the modifier will be set to this initial valuepPS[pPS.size() - 1].modifier.x = 1.0f;pPS[pPS.size() - 1].modifier.y = 1.0f;pPS[pPS.size() - 1].modifier.z = 1.0f;pPS[pPS.size() - 1].modifier.w = 1.0f;//modify is what will be sent to the constant buffermodify.modifier = pPS[pPS.size() - 1].modifier;//constant buffer setup section STARTD3D11_BUFFER_DESC bd;ZeroMemory(&bd, sizeof(bd));bd.BindFlags = D3D11_BIND_CONSTANT_BUFFER;bd.ByteWidth = sizeof(modify);bd.Usage = D3D11_USAGE_DEFAULT;HRESULT hr = dev->CreateBuffer(&bd, 0, &pPS[pPS.size() - 1].g_pConstantBuffer11);if( !FAILED( hr ) )devcon->VSSetConstantBuffers( 0, 1, &pPS[pPS.size() - 1].g_pConstantBuffer11 );//constant buffer setup section ENDD3D11_INPUT_ELEMENT_DESC ied[] ={{"POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0},{"COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0},{"UV", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 28, D3D11_INPUT_PER_VERTEX_DATA, 0},}; dev->CreateInputLayout(ied, 3, VS->GetBufferPointer(), VS->GetBufferSize(), &pLayout[pLayout.size() - 1]);return Vector2i(pPS.size() -1, pVS.size() - 1);} This part of the code I saw so many different variations on. This one worked for me (finally).D3D11_BUFFER_DESC bd;ZeroMemory(&bd, sizeof(bd));bd.BindFlags = D3D11_BIND_CONSTANT_BUFFER;bd.ByteWidth = sizeof(modify);bd.Usage = D3D11_USAGE_DEFAULT;HRESULT hr = dev->CreateBuffer(&bd, 0, &pPS[pPS.size() - 1].g_pConstantBuffer11);if( !FAILED( hr ) )devcon->VSSetConstantBuffers( 0, 1, &pPS[pPS.size() - 1].g_pConstantBuffer11 ); I selected my shader for drawing here.void Shaders::SetShader(ID3D11DeviceContext *devcon, int index){if (cShade == index) return;cShade = index;devcon->VSSetShader(pVS[index], 0, 0);devcon->PSSetShader(pPS[index].shader, 0, 0);devcon->IASetInputLayout(pLayout[index]);SetConstantBuffer(devcon, pPS[cShade].modifier);} This code is used after I select the shader for the current draw (or when the shader is first selected). This will update the constant buffer to a new value. I can use it for color picking and other fun stuff.void Shaders::SetConstantBuffer(ID3D11DeviceContext *devcon, Vector4f aMod){modify.modifier = aMod;devcon->UpdateSubresource(pPS[cShade].g_pConstantBuffer11, 0, 0, &modify, 0, 0);devcon->PSSetConstantBuffers(0, 1, &pPS[cShade].g_pConstantBuffer11);} And this is the shader for my ellipsestruct VOut{ float4 position : SV_POSITION; float4 color : COLOR; float2 uv : UV;};cbuffer VS_CONSTANT_BUFFER : register(b0){ float4 modifier;};VOut VShader(float4 position : POSITION, float4 color : COLOR, float2 uv : UV){ VOut output; output.position = position; output.color = color; output.uv = uv; return output;}float4 PShader(float4 position : SV_POSITION, float4 color : COLOR, float2 uv : UV) : SV_TARGET{ float result = (uv.x * uv.x + uv.y * uv.y); if (color.a < 1.0) color = float4(.50, .50, .50, 1.0) * color; if (result > 1) discard; if (modifier.w == 0.0) { color.r = modifier.x; color.g = modifier.y; color.b = modifier.z; color.a = 1.0; } return color;}  Forgot Color Picking. The Color format of the 1x1 texture must be the same as your backbuffer, or this is SO fail (took a while on that). The mouse must be in bounds or the srcbox will be said to be invalid.Vector4f PickColor(int the2d, int x, int y, ID3D11Device *dev, ID3D11DeviceContext *devcon){ID3D11Texture2D *BackBuffer;HRESULT hr = swapchain->GetBuffer( 0, __uuidof( ID3D11Texture2D ), reinterpret_cast< void** >( &BackBuffer ));Vector4f a = Vector4f(0, 0, 0 ,0);ID3D11Texture2D *Surface;D3D11_TEXTURE2D_DESC StagedDesc = {1,//Width;1,//Height;1,//MipLevels;1,//ArraySize;DXGI_FORMAT_R8G8B8A8_UNORM,//DXGI_FORMAT Format;1, 0,//DXGI_SAMPLE_DESC SampleDesc;D3D11_USAGE_STAGING,//D3D11_USAGE Usage;0,//UINT BindFlags;D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE,//UINT CPUAccessFlags;0//UINT MiscFlags;};dev->CreateTexture2D( &StagedDesc, NULL, &Surface);D3D11_BOX srcBox;srcBox.left = x;srcBox.right = srcBox.left + 1;srcBox.top = y;srcBox.bottom = srcBox.top + 1;srcBox.front = 0;srcBox.back = 1;devcon->CopySubresourceRegion(Surface, 0, 0, 0, 0, BackBuffer, 0, &srcBox);D3D11_MAPPED_SUBRESOURCE msr;if (devcon->Map(Surface, 0, D3D11_MAP_READ_WRITE, 0, &msr) != S_OK) return Vector4f(-1, -1, -1, -1);void *pixelA = msr.pData;std::vector pixel;pixel.resize(4);memcpy(&pixel, pixelA, 4);a.x = (float)pixel;a.y = (float)pixel;a.z = (float)pixel;a.w = (float)pixel;pixel.resize(0);devcon->Unmap(Surface, 0);Surface->Release();BackBuffer->Release();return a;}
10. ## C++ porting progress

I am using visual c++ 2010 express, I somewhat like it.  I got used to code::blocks for my c++.  And eclipse for Android/Java.  It has been interesting actually learning some directx, but I like opengl better still.
11. ## Vector Graphics

But I like its efficiency with multiple platform and resolutions.
12. ## Videolog #7 - Answering questions & a 80's montage.

I played the alpha demo on android.......release game, must play more
13. ## Bezier, it's french

It shouldn't be too hard to implement.  You would just interpolate the z as well.  You would probably use 4 control points over a grid.  I believe I have seen examples of it.
14. So I got bezier curves kickin', along with variable width of the start, middle, and end. If you have not used bezier ([be.zje]) is actually not a hard concept, but very effective. They use control points to modify a line interpolation from straight line into a curve. Coding Math 19 was very helpful. I used cubic bezier, so I have a start point, end point, and two control points. This is the code, to which I got directly from the video, but it is apparently just the code for quadratic bezier (1 control point) and Cubic bezier (2 control point). t is what percent along the line you are at (between 0.0f and 1.0f). You input the start, 1 or 2 control points depending, and the end point. You give the t and it will change pFinal to the correct point along the curve. The smaller the increments you give for t, the smoother the curve will look. All the curves in the picture are 20 segments. void QuadraticBezier(Vector2f p0, Vector2f p1, Vector2f p2, float t, Vector2f& pFinal){pFinal.x = powf(1.0f - t, 2.0f) * p0.x + (1 - t) * 2.0f * t * p1.x + t * t * p2.x;pFinal.y = powf(1.0f - t, 2.0f) * p0.y + (1 - t) * 2.0f * t * p1.y + t * t * p2.y; }void CubicBezier(Vector2f p0, Vector2f p1, Vector2f p2, Vector2f p3, float t, Vector2f& pFinal){pFinal.x = powf(1.0f - t, 3.0f) * p0.x +powf(1 - t, 2) * 3.0f * t * p1.x +(1 - t) * 3 * t * t * p2.x + t * t * t * p3.x;pFinal.y = powf(1.0f - t, 3.0f) * p0.y +powf(1 - t, 2) * 3.0f * t * p1.y +(1 - t) * 3 * t * t * p2.y + t * t * t * p3.y;} I also used a function I wrote called Wide. It uses the start, middle, and ending widths are parameters. t is the same as the curve. It calculates how wide the line will be. Before halfway through, it ignores the ending width. After halfway through, it ignores the beginning width. It was cleaner than having all this in the loop creating the curve.Vector2f Wide(Vector2f a, Vector2f b, Vector2f c, float t){float x, y;if (t == 0.0f){x = a.x;y = a.y;}else if (t < .5f){float d = t * 2.0f;x = a.x * (1.0f - d) + b.x * d;y = a.y * (1.0f - d) + b.y * d;}else if (t == .5f){x = b.x;y = b.y;}else{t = t - .5f;float d = t * 2.0f;x = b.x * (1.0f - d) + c.x * d;y = b.y * (1.0f - d) + c.y * d;}return Vector2f (x, y);} [sharedmedia=gallery:images:5779]
15. ## Ellipses

Just realized the sqrt part was not needed.  Anything less than one squared will still be less than one.  Anything more than one squared will still be more than one.
• Advertisement
×

## Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!