-2

I'm trying to dynamically allocate a float array (distances) but stepping through the debugger shows that it only allocates just one for some reason. I have already tried out std::vector and it works ok but it then fails at Vec2 * points = Util::BCurvePerpPoint(i, p1, p2, p3, this->distances, this->m_NumGeoms * 2). The thing is that distances will not change size for the life of the object so it's kind of overkill to use std::vector. The only thing I'm using std::vector in is the Draw function (which I'm thinking I can fix that up to be static in size or something but if step changes, then the size of the array would change so... yeah...).

Note: Util::BCurvePerpPoint returns an array of Vec2 where the first one is the Bézier curve point at time i. All it does is provide points at a perpendicular line of the tangent of the Bézier curve. Function prototype:
BCurvePerpPoint(float time, Vec2 p1, Vec2 p2, Vec2 p3, float * distance, const int numDists);

Header:

#ifndef _H_HOLDTAIL_
#define _H_HOLDTAIL_
#pragma once
#include "../../OD_Draw2d.h"

namespace Game {
    struct HoldTailGeom {
        float d1,d2;
        ColorF color1, color2;
        uint32 packedCol1, packedCol2;

        HoldTailGeom() :
            d1(0.0f),
            d2(0.0f),
            color1(0.0f, 0.0f, 0.0f, 0.0f),
            color2(0.0f, 0.0f, 0.0f, 0.0f),
            packedCol1(0),
            packedCol2(0)
        {};
    };

    class HoldTail {
    public:
        HoldTail(HoldTailGeom * geoms, const unsigned int numGeoms);
        ~HoldTail();

        void Draw(Vec2 p1, Vec2 p2, Vec2 p3, float tStart, float tEnd, float step = 0.05f, bool isolatedDraw = false);
        void Draw(Vec2 p1, Vec2 p2, Vec2 p3, float tStart, float tEnd, int numPoints, bool isolatedDraw = false);
    private:
        HoldTailGeom * m_Geoms;
        unsigned int m_NumGeoms;
        float * distances;

        //std::vector<float> distances;

        std::shared_ptr<OD_Draw2d> OD_Draw2dPtr;
        std::vector<SVF_P3F_C4B_T2F> *line;
    };
}

#endif //_H_HOLDTAIL_

Code:

#include <StdAfx.h>
#include "HoldTail.h"

namespace Game {
    HoldTail::HoldTail(HoldTailGeom * geoms, const unsigned int numGeoms) : m_Geoms(geoms), m_NumGeoms(numGeoms) {
        this->line = new std::vector<SVF_P3F_C4B_T2F>[numGeoms];
        this->distances = new float[numGeoms * 2]();

        //distances = new std::vector<float>();

        for (int i = 0; i < numGeoms; i++) { //for each geometry
            //convert the colors to uint32 for quicker assignment to vector data.
            this->m_Geoms[i].packedCol1 = this->m_Geoms[i].color1.pack_argb8888();
            this->m_Geoms[i].packedCol2 = this->m_Geoms[i].color2.pack_argb8888();
            //convert the distances to an array that we can use.
            //int i1 = i * 2;
            //int i2 = (i * 2) + 1;
            this->distances[i * 2] = m_Geoms[i].d1;
            this->distances[(i * 2) + 1] = m_Geoms[i].d2;
            //this->distances.push_back(m_Geoms[i].d1);
            //this->distances.push_back(m_Geoms[i].d2);
        }

        //this->distances.shrink_to_fit();
    }

    HoldTail::~HoldTail() {
        for (int i = 0; i < this->m_NumGeoms; i++) this->line[i].clear(); //clear the data just to be sure.
        delete[] this->line;
        delete[] this->distances;
        //this->distances.clear();
    }

    void HoldTail::Draw(Vec2 p1, Vec2 p2, Vec2 p3, float tStart, float tEnd, int numPoints, bool isolatedDraw) {
        if (tStart >= tEnd) return;
        this->Draw(p1, p2, p3, tStart, tEnd, (float)((float)(tEnd - tStart) / (float)(numPoints)), isolatedDraw);
    }

    void HoldTail::Draw(Vec2 p1, Vec2 p2, Vec2 p3, float tStart, float tEnd, float step, bool isolatedDraw) {
        if (tStart >= tEnd) return;

        for (float i = tStart; i < tEnd+step; i += step) { //from start time to end time with a step between each
            Vec2 * points = Util::BCurvePerpPoint(i, p1, p2, p3, this->distances, this->m_NumGeoms * 2); //calculate the distances at time i.

            for (int i2 = 0; i2 < this->m_NumGeoms; i2++) { //for each geometry
                SVF_P3F_C4B_T2F tmp;

                //push back the vectors
                tmp.xyz = Vec3(points[(i2 * 2)+1].x, points[(i2 * 2)+1].y, 1);
                tmp.color.dcolor = this->m_Geoms[i2].packedCol1;
                tmp.st = Vec2(0, 0);
                this->line[i2].push_back(tmp);

                tmp.xyz = Vec3(points[(i2 * 2)+2].x, points[(i2 * 2)+2].y, 1);
                tmp.color.dcolor = this->m_Geoms[i2].packedCol2;
                this->line[i2].push_back(tmp);
            }
        }

        if (isolatedDraw) this->OD_Draw2dPtr->BeginDraw2d(1280, 720);
            for (int i = 0; i < this->m_NumGeoms; i++) { //for each geometry
                this->OD_Draw2dPtr->DrawTriangleStrip(&this->line[i][0], this->line[i].size()); //draw the line
                this->line[i].clear(); //done using the line, clear it for next pass.
            }
        if (isolatedDraw) this->OD_Draw2dPtr->EndDraw2d();
    }
}

Debugging Image

melpomene
  • 84,125
  • 8
  • 85
  • 148
alatnet
  • 1
  • 2
  • 1
    A basic question -- Why don't you use `std::vector` for all of your "dynamic arrays"? Why use vector in some places, and not use it (where it would probably wise to) in others? – PaulMcKenzie Jun 05 '16 at 06:48
  • `so it's kind of overkill to use std::vector` classic premature optimization, considering other flaws in your code (tmp, for example) – strangeqargo Jun 05 '16 at 06:49
  • 3
    *The thing is, is that distances will not change size for the life of the object so it's kind of overkill to use std::vector* -- My suggestion is to use `vector` and get your program working first. Trying to optimize code that doesn't work doesn't make a lot of sense. Also: `this->line = new std::vector[numGeoms];` -- did you really want an array of vectors here? – PaulMcKenzie Jun 05 '16 at 06:52
  • Also, your program is totally broken if `HoldTail` is used as a value object (passed by value, returned by value, copied, etc.) since `HoldTail` does not adhere to the "rule of 3". Using a vector or similar container instead of pointers would alleviate that problem. – PaulMcKenzie Jun 05 '16 at 06:57
  • Hi, I agree with @PaulMcKenzie don't use pointer on std::vector to create it with proper size. Use reserve function on normal object. Second use smart pointers not raw pointers in your code. – paweldac Jun 05 '16 at 06:59
  • " the debugger shows that it only allocates just one " ... how does the debugger show that? Is there some actual problem you are experiencing? (if so, please add details). – rici Jun 05 '16 at 07:02
  • Debuggers usually show pointers as pointing to one element, because that's what pointers do. (If it's the first element of an array, the debugger doesn't know that.) – molbdnilo Jun 05 '16 at 08:02
  • This isn't the problem, but names that begin with an underscore followed by a capital letter (`_H_HOLDTAIL_`) and names that contain two consecutive underscores are reserved to the implementation. Don't use them. – Pete Becker Jun 05 '16 at 11:55
  • ok, in order: 1. Distance does not change size for the life of the object where as in draw, the number of vectors (3D) does, so a fixed sized array for distances is better than std::vector. 2. i did try using std::vector for distance and it did "work" but it failed at `BCurvePerpPoint` for some reason. 3. HoldTail IS NOT a value object. 4. I'm an old c++ coder, i've worked with raw pointers and my deconstructor is handling freeing up memory so there's no memory leaks. 5. Check the end of the post, i have an image. 6. Include guards, that's what `_H_HOLDTAIL_` is... – alatnet Jun 05 '16 at 14:13
  • oh i forgot, the reason for `this->line = new std::vector[numGeoms];` is that im drawing multiple lines of triangle strip geometries. so to separate each triangle strip, im using a fixed sized array of std::vectors based on how many lines/geoms are passed to the constructor. – alatnet Jun 05 '16 at 14:34

1 Answers1

0

Fixed it... Apparently the m_Geoms wasn't getting any data even though in the constructor i had it assigned with m_Geoms(geoms). It didn't copy the array over... So I adjusted the constructor and deconstructor respectively:

HoldTail::HoldTail(HoldTailGeom * geoms, const unsigned int numGeoms) : m_NumGeoms(numGeoms), distances(nullptr), line(nullptr) {
        this->line = new std::vector<SVF_P3F_C4B_T2F>[numGeoms];
        this->distances = new float[numGeoms * 2]();
        this->m_Geoms = new HoldTailGeom[numGeoms];

        //distances = new std::vector<float>();

        for (int i = 0; i < numGeoms; i++) { //for each geometry
            //copy data...
            this->m_Geoms[i].d1 = geoms[i].d1;
            this->m_Geoms[i].d2 = geoms[i].d2;
            this->m_Geoms[i].color1 = geoms[i].color1;
            this->m_Geoms[i].color2 = geoms[i].color2;
            //convert the colors to uint32 for quicker assignment to vector data.
            this->m_Geoms[i].packedCol1 = geoms[i].color1.pack_argb8888();
            this->m_Geoms[i].packedCol2 = geoms[i].color2.pack_argb8888();
            //convert the distances to an array that we can use.
            //int i1 = i * 2;
            //int i2 = (i * 2) + 1;
            this->distances[i * 2] = m_Geoms[i].d1;
            this->distances[(i * 2) + 1] = m_Geoms[i].d2;
            //this->distances.push_back(m_Geoms[i].d1);
            //this->distances.push_back(m_Geoms[i].d2);
        }

        //this->distances.shrink_to_fit();
    }

    HoldTail::~HoldTail() {
        for (int i = 0; i < this->m_NumGeoms; i++) this->line[i].clear(); //clear the data just to be sure.
        delete[] this->line;
        delete[] this->distances;
        delete[] this->m_Geoms;
        //this->distances.clear();
    }

which fixed the issue. guess i've been programming on java for too long... >.<

alatnet
  • 1
  • 2